diff --git a/src/modules/Image/encodings/bmp.c b/src/modules/Image/encodings/bmp.c index 605a6f43e8252c0de30e6e393a14bf6c7266cb72..316ffc8d492c161667351210053b3205e4798c85 100644 --- a/src/modules/Image/encodings/bmp.c +++ b/src/modules/Image/encodings/bmp.c @@ -1,9 +1,9 @@ -/* $Id: bmp.c,v 1.8 1999/05/02 15:33:19 mirar Exp $ */ +/* $Id: bmp.c,v 1.9 1999/05/02 18:26:42 mirar Exp $ */ /* **! module Image **! note -**! $Id: bmp.c,v 1.8 1999/05/02 15:33:19 mirar Exp $ +**! $Id: bmp.c,v 1.9 1999/05/02 18:26:42 mirar Exp $ **! submodule BMP **! **! This submodule keeps the BMP (Windows Bitmap) @@ -22,7 +22,7 @@ #include <ctype.h> #include "stralloc.h" -RCSID("$Id: bmp.c,v 1.8 1999/05/02 15:33:19 mirar Exp $"); +RCSID("$Id: bmp.c,v 1.9 1999/05/02 18:26:42 mirar Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -383,7 +383,7 @@ void i_img_bmp__decode(INT32 args,int header_only) n++; - s+=54; + s+=54; /* fuji mode doesn't care */ len-=54; break; @@ -420,8 +420,8 @@ void i_img_bmp__decode(INT32 args,int header_only) break; default: - error("Image.BMP.decode: not a BMP " - "(illegal info size %ld, expected 40 or 12)\n", + error("Image.BMP.decode: not a known BMP type " + "(illegal info size %ld, expected 68, 40 or 12)\n", int_from_32bit(s+14)); } @@ -513,16 +513,19 @@ void i_img_bmp__decode(INT32 args,int header_only) img=(struct image*)get_storage(o,image_program); n++; - if (comp > 2) - error("Image.BMP.decode: illegal compression: %d\n",comp); + if (int_from_32bit(os+10)) + { + s=os+int_from_32bit(os+10); + len=olen-int_from_32bit(os+10); + } - switch (bpp) + if (len>0) switch (bpp) { case 24: if (comp) error("Image.BMP.decode: can't handle compressed 24bpp BMP\n"); - skip=(4-(img->xsize*3)&3)&3; + skip=(4-((img->xsize*3)&3))&3; j=(len)/3; y=img->ysize; @@ -542,33 +545,182 @@ void i_img_bmp__decode(INT32 args,int header_only) } break; case 8: - if (comp) - error("Image.BMP.decode: can't handle compressed 8bpp BMP\n"); + if (comp != 0 && comp != 1 ) + error("Image.BMP.decode: can't handle compression %d for 8bpp BMP\n",comp); - skip=(4-img->xsize&3)&3; - j=len; - y=img->ysize; - while (j && y--) + if (comp==1) { + int i; + rgb_group *maxd=img->img+img->xsize*img->ysize; + + + /* 00 00 - end of line + 00 01 - end of data + 00 02 dx dy - move cursor + 00 x (x bytes) 00 - x bytes of data + x a - x bytes of rle data (a a ...) + */ + + y=img->ysize-1; d=img->img+img->xsize*y; - i=img->xsize; if (i>j) i=j; - j-=i; - while (i--) - *(d++)=nct->u.flat.entries[*(s++)].color; - if (j>=skip) { j-=skip; s+=skip; } + + while (j--) + { + if (!j--) break; + switch (*s) + { + case 0: + switch (s[1]) + { + case 0: + if (y!=0) y--; + d=img->img+img->xsize*y; + break; + case 1: + goto done_rle8; + case 2: + error("Image.BMP.decode: advanced RLE " + "decompression (cursor movement) " + "is unimplemented (please send this " + "image to mirar@idonex.se)\n"); + default: + error("Image.BMP.decode: advanced RLE " + "decompression (non-rle data) " + "is unimplemented (please send this " + "image to mirar@idonex.se)\n"); + } + break; + default: + for (i=0; i<s[0] && d<maxd; i++) + if (s[1]>nct->u.flat.numentries) + d++; + else + *(d++)=nct->u.flat.entries[s[1]].color; + break; + } + s+=2; + } + done_rle8: + } + else + { + skip=(4-(img->xsize&3))&3; + j=len; + y=img->ysize; + while (j && y--) + { + d=img->img+img->xsize*y; + i=img->xsize; if (i>j) i=j; + j-=i; + while (i--) + *(d++)=nct->u.flat.entries[*(s++)].color; + if (j>=skip) { j-=skip; s+=skip; } + } } break; case 4: - if (comp == 1) - error("Image.BMP.decode: can't handle RLE4 compressed 4bpp BMP\n"); + if (comp != 0 && comp != 2 ) + error("Image.BMP.decode: can't handle compression %d for 4bpp BMP\n",comp); if (comp == 2) /* RLE4 */ { + int i; + rgb_group *maxd=img->img+img->xsize*img->ysize; + y=img->ysize-1; + d=img->img+img->xsize*y; + + /* 00 00 - end of line + 00 01 - end of data + 00 02 dx dy - move cursor + 00 x ((x+1)/2 bytes) 00 - x nibbles of data + x ab - x nibbles of rle data (a b a b a ...) + */ + + j=len; + while (j--) + { + if (!j--) break; + switch (*s) + { + case 0: + switch (s[1]) + { + case 0: +#if RLE_DEBUG + fprintf(stderr,"end of line %5d %02x %02x\n", + j,s[0],s[1]); +#endif + if (y>0) y--; + d=img->img+img->xsize*y; + + break; + case 1: +#if RLE_DEBUG + fprintf(stderr,"end of data %5d %02x %02x\n", + j,s[0],s[1]); +#endif + goto done_rle4; + case 2: + error("Image.BMP.decode: advanced RLE " + "decompression (cursor movement) " + "is unimplemented (please send this " + "image to mirar@idonex.se)\n"); +#if RLE_DEBUG + if (j<2) break; + fprintf(stderr,"cursor " + "%5d %02x %02x %02x %02x\n", + j,s[0],s[1],s[2],s[3]); + j-=2; s+=2; +#endif + break; + default: + error("Image.BMP.decode: advanced RLE " + "decompression (non-rle data) " + "is unimplemented (please send this " + "image to mirar@idonex.se)\n"); +#if RLE_DEBUG + fprintf(stderr,"data %5d %02x %02x [ ", + j,s[0],s[1]); + fflush(stderr); + + for (i=0; i<(s[1]+1)/2; i++) + fprintf(stderr,"%02x ",s[2+i]); + fprintf(stderr,"] %02x\n",s[2+i]); + + j-=2; s+=2; + j-=i; s+=i; +#endif + + break; + } + break; + default: +#if RLE_DEBUG + fprintf(stderr,"rle data %02x %02x\n",s[0],s[1]); +#endif + for (i=0; i<s[0] && d<maxd; i++) + { + int c; + if (i&1) + c=s[1]&15; + else + c=(s[1]>>4)&15; + + if (c>nct->u.flat.numentries) + d++; + else + *(d++)=nct->u.flat.entries[c].color; + } + break; + } + s+=2; + } + done_rle4: } else { - skip=(4-((img->xsize+1)/2)&3)&3; + skip=(4-(((img->xsize+1)/2)&3))&3; j=len; y=img->ysize; while (j && y--) @@ -589,7 +741,7 @@ void i_img_bmp__decode(INT32 args,int header_only) if (comp) error("Image.BMP.decode: can't handle compressed 1bpp BMP\n"); - skip=(4-((img->xsize+7)/8)&3)&3; + skip=(4-(((img->xsize+7)/8)&3))&3; j=len; y=img->ysize; while (j && y--)