ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/bmpfile.c
(Generate patch)

Comparing ray/src/common/bmpfile.c (file contents):
Revision 2.8 by greg, Sat Apr 10 02:54:44 2004 UTC vs.
Revision 2.13 by greg, Fri Mar 18 21:04:05 2005 UTC

# Line 10 | Line 10 | static const char RCSid[] = "$Id$";
10   #include <string.h>
11   #include "bmpfile.h"
12  
13 + #ifdef getc_unlocked            /* avoid horrendous overhead of flockfile */
14 + #undef getc
15 + #undef putc
16 + #define getc    getc_unlocked
17 + #define putc    putc_unlocked
18 + #endif
19 +
20   /* get corresponding error message */
21   const char *
22   BMPerrorMessage(int ec)
# Line 64 | Line 71 | BMPheaderOK(const BMPHeader *hdr)
71          if (hdr->compr == BI_BITFIELDS && (BMPbitField(hdr)[0] &
72                                  BMPbitField(hdr)[1] & BMPbitField(hdr)[2]))
73                  return 0;
74 <        if ((hdr->nColors < 0) | (hdr->impColors < 0))
75 <                return 0;
76 <        if (hdr->impColors > hdr->nColors)
77 <                return 0;
78 <        if (hdr->nColors > BMPpalLen(hdr))
79 <                return 0;
74 >        if (hdr->bpp > 8) {
75 >                if (hdr->nColors != 0)
76 >                        return 0;
77 >        } else {
78 >                if ((hdr->nColors < 0) | (hdr->nColors > 1<<hdr->bpp))
79 >                        return 0;
80 >                if ((hdr->impColors < 0) | (hdr->impColors > hdr->nColors))
81 >                        return 0;
82 >        }
83          return 1;
84   }
85  
# Line 136 | Line 146 | BMPReader *
146   BMPopenReader(int (*cget)(void *), int (*seek)(uint32, void *), void *c_data)
147   {
148          BMPReader       *br;
149 <        uint32          bmPos, hdrSiz;
150 <        int             palLen;
149 >        uint32          bmPos, hdrSiz, palSiz;
150 >        int             magic[2];               /* check magic number */
151  
152          if (cget == NULL)
153                  return NULL;
144        int     magic[2];               /* check magic number */
154          magic[0] = (*cget)(c_data);
155          if (magic[0] != 'B')
156                  return NULL;
# Line 184 | Line 193 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
193                  goto err;                       /* catch premature EOF */
194          if (!BMPheaderOK(br->hdr))
195                  goto err;
196 <        palLen = BMPpalLen(br->hdr);
197 <        if (br->hdr->bpp <= 8) {                /* normalize color counts */
198 <                if (br->hdr->nColors <= 0)
190 <                        br->hdr->nColors = palLen;
191 <                if (br->hdr->impColors <= 0)
192 <                        br->hdr->impColors = br->hdr->nColors;
193 <        }
196 >        palSiz = sizeof(RGBquad)*br->hdr->nColors;
197 >        if (br->hdr->impColors <= 0)
198 >                br->hdr->impColors = br->hdr->nColors;
199                                                  /* extend header */
200 <        if (bmPos < hdrSiz + sizeof(RGBquad)*palLen)
200 >        if (bmPos < hdrSiz + palSiz)
201                  goto err;
202 <        br->hdr->infoSiz = bmPos - (hdrSiz + sizeof(RGBquad)*palLen);
203 <        if (palLen > 0 || br->hdr->infoSiz > 0) {
202 >        br->hdr->infoSiz = bmPos - (hdrSiz + palSiz);
203 >        if (br->hdr->nColors > 0 || br->hdr->infoSiz > 0) {
204                  br->hdr = (BMPHeader *)realloc((void *)br->hdr,
205                                          sizeof(BMPHeader) +
206 <                                        sizeof(RGBquad)*palLen +
202 <                                        br->hdr->infoSiz);
206 >                                        palSiz + br->hdr->infoSiz);
207                  if (br->hdr == NULL)
208                          goto err;
209          }
# Line 208 | Line 212 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
212                  BMPbitField(br->hdr)[0] = (uint32)rdint32(br);
213                  BMPbitField(br->hdr)[1] = (uint32)rdint32(br);
214                  BMPbitField(br->hdr)[2] = (uint32)rdint32(br);
215 <        } else if (rdbytes((char *)br->hdr->palette,
212 <                        sizeof(RGBquad)*palLen, br) != BIR_OK)
215 >        } else if (rdbytes((char *)br->hdr->palette, palSiz, br) != BIR_OK)
216                  goto err;
217                                                  /* read add'l information */
218          if (rdbytes(BMPinfo(br->hdr), br->hdr->infoSiz, br) != BIR_OK)
# Line 232 | Line 235 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
235                                  sizeof(br->scanpos[0])*br->hdr->height);
236          }
237          br->scanpos[0] = br->fpos;
238 <        if (BMPreadScanline(br) != BIR_OK)
239 <                goto err;
237 <        return br;
238 >        if (BMPreadScanline(br) == BIR_OK)
239 >                return br;
240   err:
241          if (br->hdr != NULL)
242                  free((void *)br->hdr);
# Line 275 | Line 277 | BMPreadScanline(BMPReader *br)
277          if (br->hdr->compr == BI_UNCOMPR || br->hdr->compr == BI_BITFIELDS)
278                  return rdbytes((char *)br->scanline, n, br);
279          /*
280 <         * RLE/RLE8 Decoding
280 >         * RLE4/RLE8 Decoding
281           *
282           * Certain aspects of this scheme are completely insane, so
283           * we don't support them.  Fortunately, they rarely appear.
284           * One is the mid-file EOD (0x0001) and another is the ill-conceived
285           * "delta" (0x0002), which is like a "goto" statement for bitmaps.
286 <         * Whoever thought this up should be shot, then told why
287 <         * it's impossible to support such a scheme in any reasonable way.
286 >         * Whoever thought this up should be wrestled to the ground and told
287 >         * why it's impossible to support such a scheme in any reasonable way.
288           * Also, RLE4 mode allows runs to stop halfway through a byte,
289           * which is likewise uncodeable, so we don't even try.
290           * Finally, the scanline break is ambiguous -- we assume here that
# Line 297 | Line 299 | BMPreadScanline(BMPReader *br)
299           * is undoubtedly the most brain-dead format I've ever encountered.
300           */
301          sp = br->scanline;
302 +        n = br->hdr->width;
303 +        if (br->hdr->compr == BI_RLE4)
304 +                n = (n + 1) >> 1;
305          while (n > 0) {
306                  int     skipOdd, len, val;
307  
# Line 317 | Line 322 | BMPreadScanline(BMPReader *br)
322                                  *sp++ = val;
323                          continue;
324                  }
325 +                                        /* check for escape */
326                  switch (rdbyte(len, br)) {
327                  case EOF:
328                          return BIR_TRUNCATED;
# Line 632 | Line 638 | BMPopenWriter(void (*cput)(int, void *), int (*seek)(u
638          hdrSiz = 2 + 6*4 + 2*2 + 6*4;
639          if (hdr->compr == BI_BITFIELDS)
640                  hdrSiz += sizeof(uint32)*3;
641 <        palSiz = sizeof(RGBquad)*BMPpalLen(hdr);
641 >        palSiz = sizeof(RGBquad)*hdr->nColors;
642          scanSiz = getScanSiz(hdr);
643          bmSiz = hdr->height*scanSiz;            /* wrong if compressed */
644                                                  /* initialize writer */
# Line 732 | Line 738 | BMPwriteScanline(BMPWriter *bw)
738          n = bw->hdr->width;
739          while (n > 0) {
740                  int     cnt, val;
735
741                  cnt = findNextRun(sp, n);       /* 0-255 < n */
742 <                if (cnt >= 3) {                 /* output non-run */
742 >                if (cnt >= 3) {                 /* output absolute */
743                          int     skipOdd = cnt & 1;
744                          wrbyte(0, bw);
745                          wrbyte(cnt, bw);
# Line 747 | Line 752 | BMPwriteScanline(BMPWriter *bw)
752                  if (n <= 0)                     /* was that it? */
753                          break;
754                  val = *sp;                      /* output run */
755 <                for (cnt = 1; cnt < 255; cnt++)
756 <                        if ((!--n) | (*++sp != val))
755 >                for (cnt = 1; --n && cnt < 255; cnt++)
756 >                        if (*++sp != val)
757                                  break;
758                  wrbyte(cnt, bw);
759                  wrbyte(val, bw);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines