#include #include BITMAP *load_memory_gd(unsigned char *gd, int len, RGB *pal) { BITMAP *bmp; PALETTE tmppal; unsigned int header, width, height, truecolor, transparent, colors; int i, x, y, loc, dest_depth, bpp, want_palette; if(!pal) { want_palette = FALSE; pal = tmppal; } else want_palette = TRUE; bmp = NULL; if(len < 12) goto error; header = gd[0] << 8 | gd[1]; if(header != 65535 && header != 65534) goto error; width = gd[2] << 8 | gd[3]; height = gd[4] << 8 | gd[5]; if(width == 0 || height == 0) goto error; truecolor = gd[6]; if(truecolor) { if(len < 11) goto error; transparent = gd[7] << 24 | gd[8] << 16 | gd[9] << 8 | gd[10]; loc = 11; bpp = 24; } else { if(len < 13) goto error; colors = gd[7] << 8 | gd[8]; transparent = gd[9] << 24 | gd[10] << 16 | gd[11] << 8 | gd[12]; loc = 13; bpp = 8; for(i = 0; i < colors; i++) { pal[i].r = gd[loc]; pal[i].g = gd[loc+1]; pal[i].b = gd[loc+2]; loc += 4; } } dest_depth = _color_load_depth(bpp, FALSE); bmp = create_bitmap_ex(bpp, width, height); if(!bmp) goto error; if(truecolor) { for(y = 0; y < height; y++) for(x = 0; x < width; x++) { _putpixel24(bmp, x, y, makecol24(gd[loc+1], gd[loc+2], gd[loc+3])); loc += 4; } } else { for(y = 0; y < height; y++) for(x = 0; x < width; x++) { bmp->line[y][i] = gd[loc]; loc++; } } if(dest_depth != bpp) { if((bpp != 8) && (!want_palette)) pal = NULL; bmp = _fixup_loaded_bitmap(bmp, pal, dest_depth); } if((bpp != 8) && (dest_depth != 8) && want_palette) generate_332_palette(pal); return bmp; error: if(bmp != NULL) destroy_bitmap(bmp); return NULL; } /* TODO: fix this-- needs to be debugged: generates bad gd files */ unsigned char *save_memory_gd(BITMAP *bmp, RGB *pal, int *len) { unsigned char *gd, *data; int loc, y, x, depth, i, size; gd = NULL; depth = bitmap_color_depth(bmp); if(depth == 8) size = bmp->w * bmp->h + 256 * 4 + 13; else size = bmp->w * bmp->h * 4 + 11; gd = malloc(size); if(gd == NULL) goto error; gd[0] = (depth == 8) ? 0xff : 0xfe; gd[1] = 0xff; gd[2] = bmp->w >> 8; gd[3] = bmp->w & 0xff; gd[4] = bmp->h >> 8; gd[5] = bmp->h & 0xff; gd[6] = (depth > 8); if(depth > 8) { gd[7] = 0xff; gd[8] = 0xff; gd[9] = 0xff; gd[10] = 0xff; data = gd + 11; } else { gd[7] = 1; gd[8] = 0; gd[9] = 0xff; gd[10] = 0xff; gd[11] = 0xff; gd[12] = 0xff; data = gd + 13; for(i = 0; i < 256; i++) { *(data + 0) = 0; *(data + 1) = pal[i].r * 4; *(data + 2) = pal[i].g * 4; *(data + 3) = pal[i].b * 4; data += 4; } } switch(depth) { case 8: for(y = 0; y < bmp->h; y++) for(x = 0; x < bmp->w; x++) *data++ = _getpixel(bmp, x, y); break; case 15: for(y = 0; y < bmp->h; y++) for(x = 0; x < bmp->w; x++) { int c = _getpixel15(bmp, x, y); *(data + 0) = 0; *(data + 1) = getr15(c); *(data + 2) = getg15(c); *(data + 3) = getb15(c); data += 4; } break; case 16: for(y = 0; y < bmp->h; y++) for(x = 0; x < bmp->w; x++) { int c = _getpixel16(bmp, x, y); *(data + 0) = 0; *(data + 1) = getr16(c); *(data + 2) = getg16(c); *(data + 3) = getb16(c); data += 4; } break; case 24: for(y = 0; y < bmp->h; y++) for(x = 0; x < bmp->w; x++) { int c = _getpixel24(bmp, x, y); *(data + 0) = 0; *(data + 1) = getr24(c); *(data + 2) = getg24(c); *(data + 3) = getb24(c); data += 4; } break; case 32: for(y = 0; y < bmp->h; y++) for(x = 0; x < bmp->w; x++) { int c = _getpixel32(bmp, x, y); *(data + 0) = geta32(c); *(data + 1) = getr32(c); *(data + 2) = getg32(c); *(data + 3) = getb32(c); data += 4; } break; } if(len) *len = size; return gd; error: return NULL; }