![]() |
|
[A5] trouble writing ALLEGRO_BITMAP to zip file |
awergh
Member #15,474
January 2014
|
So I have an ALLEGRO_BITMAP in memory and I want to save the image in this case a tga file to a zip file. Currently I am using libzip to write the zip file. I could just use physfs to grab the file instead of where it has been loaded into memory but I don't think it matters too much just as long as I have a file in memory I can do stuff with. Basically the issue is that the files that are created in the archive are unreadable and often just garbage and don't have the expected end for a TGA file. I also tried al_load_bitmap_f(memfile ".tga") just after saving it and the bmp was always null, not sure if I was using it wrong or not though. It is true that if I save the file and then put it in the archive it works fine that way but I'd prefer to have to save it somewhere to disk if I can help it. I'm sure there is something important I don't realise oh and al_init_image_addon(); and al_init() have been called so its not that. 1
2 PHYSFS_addToSearchPath(al_path_cstr(setPathGlb,'/'),1);
3 PHYSFS_File *currentGraphicFile = PHYSFS_openRead(it->first.c_str());
4 int length = PHYSFS_fileLength(currentGraphicFile);
5 PHYSFS_close(currentGraphicFile);
6
7 void *fileBuffer;
8 void *graphicBuffer;
9
10 int dot = it->first.find_last_of(".");
11 std::string basename = it->first.substr(0, dot);
12
13 std::unordered_map<std::string, Graphic*>::const_iterator got;
14 if( (got = currentSetMap->find(basename)) != currentSetMap->end() )
15 {
16
17 length+=8000; //just make it much bigger for now
18
19 ALLEGRO_BITMAP *bmp = got->second->getBitmapImage();
20
21 fileBuffer = malloc(length);
22 ALLEGRO_FILE *memfile = al_open_memfile(fileBuffer, length, "w+b");
23
24 bool result = al_save_bitmap_f(memfile, ".tga", bmp); //temp as .tga instead of generically
25 graphicBuffer = malloc(length);
26
27 size_t bytes = al_fread(memfile, graphicBuffer, length);
28 printf("bytes=%i\n", bytes);
29 printf("eof?=%i\n",al_feof(memfile));
30 printf("error?=%i\n",al_ferror(memfile));
31
32
33 zip_source *currentGraphicSource = zip_source_buffer(z, graphicBuffer, length, 0);
34 zip_add(z, it->first.c_str(), currentGraphicSource);
35
36 al_fclose(memfile);
37 length-=8000;
38 }
39
40 free(fileBuffer);
41 free(graphicBuffer);
|
Elias
Member #358
May 2000
|
After your al_save_bitmap_f call the file pointer will be at the end of the file just written. So the next al_fread cannot work. Either use al_fseek to reset the position or close and re-open the memfile. -- |
awergh
Member #15,474
January 2014
|
thought it might be something obvious like that but I'm still not quite there yet. drawing the bmp from the memfile works fine but saving it either to file or to a buffer doesn't seem to be working for me. Ignoring writing to the buffer for now and trying to write to file it looks like it almost creates a valid tga file but irfanview can't read it but at least it thinks its a tga file instead of unrecognised now. EDIT: well that was kindof dumb of me forgetting to close the file.... EDIT2: Lets try again and do the real problem of writing to the buffer It seems odd to me that the bytes written to the buffer is significantly bigger then the bytes written to the memfile. Something like 11000 compared to 4116 I expected a little bit more but not nearly that much. I definitely know that it is in the memfile because I can al_load_bitmap_f() from it and draw it on the screen. But I've had no luck actually writing it to file and instead get an invalid TGA file. 1fileBuffer = malloc(length);
2 ALLEGRO_FILE *memfile = al_open_memfile(fileBuffer, length, "rw");
3
4 int pos = al_ftell(memfile);
5 printf("initpos=%i\n", pos);
6
7 bool result = al_save_bitmap_f(memfile, ".tga", bmp); //temp as .tga
8 printf("save result = %i\n", result);
9
10 int endpos = al_ftell(memfile);
11 printf("save endpos=%i\n", endpos);
12 length = endpos;
13
14 al_fseek(memfile,0,ALLEGRO_SEEK_SET);
15
16 length*=3;
17 graphicBuffer = malloc(length);
18 void *buf = malloc(length);
19
20 int bytes = al_fread(memfile, buf, length);
21 printf("bytes=%i\n", bytes);
22 printf("eof?=%i\n",al_feof(memfile));
23 printf("error?=%i\n",al_ferror(memfile));
24 al_fseek(memfile,0,0);
25
26
27
28 zip_source *currentGraphicSource = zip_source_buffer(z, graphicBuffer, bytes+1, 0);
29
30 zip_add(z, it->first.c_str(), currentGraphicSource);
31 free(buf);
32 al_fclose(memfile);
EDIT3: |
|