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.5 by greg, Sat Mar 27 05:43:37 2004 UTC vs.
Revision 2.12 by greg, Tue Sep 14 02:53:50 2004 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 138 | Line 145 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
145          BMPReader       *br;
146          uint32          bmPos, hdrSiz;
147          int             palLen;
148 +        int     magic[2];               /* check magic number */
149  
150          if (cget == NULL)
151                  return NULL;
144        int     magic[2];               /* check magic number */
152          magic[0] = (*cget)(c_data);
153          if (magic[0] != 'B')
154                  return NULL;
# Line 232 | Line 239 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
239                                  sizeof(br->scanpos[0])*br->hdr->height);
240          }
241          br->scanpos[0] = br->fpos;
242 <        if (BMPreadScanline(br) != BIR_OK)
243 <                goto err;
237 <        return br;
242 >        if (BMPreadScanline(br) == BIR_OK)
243 >                return br;
244   err:
245          if (br->hdr != NULL)
246                  free((void *)br->hdr);
# Line 255 | Line 261 | BMPisGrayscale(const BMPHeader *hdr)
261                  return -1;
262          if (hdr->bpp > 8)               /* assume they had a reason for it */
263                  return 0;
264 <        for (rgbp = hdr->palette, n = hdr->impColors; n-- > 0; rgbp++)
264 >        for (rgbp = hdr->palette, n = hdr->nColors; n-- > 0; rgbp++)
265                  if (((rgbp->r != rgbp->g) | (rgbp->g != rgbp->b)))
266                          return 0;
267          return 1;                       /* all colors neutral in map */
# Line 275 | Line 281 | BMPreadScanline(BMPReader *br)
281          if (br->hdr->compr == BI_UNCOMPR || br->hdr->compr == BI_BITFIELDS)
282                  return rdbytes((char *)br->scanline, n, br);
283          /*
284 <         * RLE/RLE8 Decoding
284 >         * RLE4/RLE8 Decoding
285           *
286           * Certain aspects of this scheme are completely insane, so
287           * we don't support them.  Fortunately, they rarely appear.
288 <         * One is the mid-file EOD (0x0001) and another is the insane
288 >         * One is the mid-file EOD (0x0001) and another is the ill-conceived
289           * "delta" (0x0002), which is like a "goto" statement for bitmaps.
290 <         * Whoever thought this up should be shot, then told why
291 <         * it's impossible to support in any reasonable way.
290 >         * Whoever thought this up should be wrestled to the ground and told
291 >         * why it's impossible to support such a scheme in any reasonable way.
292           * Also, RLE4 mode allows runs to stop halfway through a byte,
293           * which is likewise uncodeable, so we don't even try.
294           * Finally, the scanline break is ambiguous -- we assume here that
# Line 291 | Line 297 | BMPreadScanline(BMPReader *br)
297           * the end of the scanline, assuming the next bit of data belongs
298           * the following scan.  If a break follows the last pixel, as it
299           * seems to in the files I've tested out of Photoshop, you end up
300 <         * painting every other line black.  BTW, I assume any skipped
300 >         * painting every other line black.  Also, I assume any skipped
301           * pixels are painted with color 0, which is often black.  Nowhere
302           * is it specified what we should assume for missing pixels.  This
303           * is undoubtedly the most brain-dead format I've ever encountered.
304           */
305          sp = br->scanline;
306 +        n = br->hdr->width;
307 +        if (br->hdr->compr == BI_RLE4)
308 +                n = (n + 1) >> 1;
309          while (n > 0) {
310                  int     skipOdd, len, val;
311  
# Line 317 | Line 326 | BMPreadScanline(BMPReader *br)
326                                  *sp++ = val;
327                          continue;
328                  }
329 +                                        /* check for escape */
330                  switch (rdbyte(len, br)) {
331                  case EOF:
332                          return BIR_TRUNCATED;
333                  case 0:                 /* end of line */
334                          while (n--)
335                                  *sp++ = 0;
336 +                        /* leaves n == -1 as flag for test after loop */
337                          continue;
338                  case 1:                 /* end of bitmap */
339                  case 2:                 /* delta */
# Line 347 | Line 358 | BMPreadScanline(BMPReader *br)
358                          return BIR_TRUNCATED;
359          }
360                                          /* verify break at end of line */
361 <        if (rdbyte(n, br) != 0 || (rdbyte(n, br) != 0 &&
362 <                                (n != 1 || br->yscan != br->hdr->height-1)))
361 >        if (!n && (rdbyte(n, br) != 0 || (rdbyte(n, br) != 0 &&
362 >                                (n != 1 || br->yscan != br->hdr->height-1))))
363                  return BIR_RLERROR;
364          if (br->seek != NULL)           /* record next scanline position */
365                  br->scanpos[br->yscan + 1] = br->fpos;
# Line 599 | Line 610 | wrseek(uint32 pos, BMPWriter *bw)
610   {
611          if (pos == bw->fpos)
612                  return BIR_OK;
613 <        if (bw->seek == NULL) {
614 <                if (pos < bw->fpos)
604 <                        return BIR_SEEKERR;
605 <                while (bw->fpos < pos)
606 <                        wrbyte(0, bw);
607 <                return BIR_OK;
608 <        }
613 >        if (bw->seek == NULL)
614 >                return BIR_SEEKERR;
615          if ((*bw->seek)(pos, bw->c_data) != 0)
616                  return BIR_SEEKERR;
617          bw->fpos = pos;
# Line 736 | Line 742 | BMPwriteScanline(BMPWriter *bw)
742          n = bw->hdr->width;
743          while (n > 0) {
744                  int     cnt, val;
739
745                  cnt = findNextRun(sp, n);       /* 0-255 < n */
746 <                if (cnt >= 3) {                 /* output non-run */
746 >                if (cnt >= 3) {                 /* output absolute */
747                          int     skipOdd = cnt & 1;
748                          wrbyte(0, bw);
749                          wrbyte(cnt, bw);
# Line 751 | Line 756 | BMPwriteScanline(BMPWriter *bw)
756                  if (n <= 0)                     /* was that it? */
757                          break;
758                  val = *sp;                      /* output run */
759 <                for (cnt = 1; cnt < 255; cnt++)
760 <                        if (!--n | *++sp != val)
759 >                for (cnt = 1; --n && cnt < 255; cnt++)
760 >                        if (*++sp != val)
761                                  break;
762                  wrbyte(cnt, bw);
763                  wrbyte(val, bw);
# Line 760 | Line 765 | BMPwriteScanline(BMPWriter *bw)
765          bw->yscan++;                            /* write line break or EOD */
766          if (bw->yscan == bw->hdr->height) {
767                  wrbyte(0, bw); wrbyte(1, bw);   /* end of bitmap marker */
768 <                if (bw->seek == NULL || (*bw->seek)(2, bw->c_data) != 0)
768 >                if (wrseek(2, bw) != BIR_OK)
769                          return BIR_OK;          /* no one may care */
770 <                bw->fpos = 2;
771 <                wrint32(bw->flen-bw->fbmp, bw); /* output correct bitmap length */
770 >                wrint32(bw->flen, bw);          /* correct file length */
771 >                if (wrseek(34, bw) != BIR_OK)
772 >                        return BIR_OK;
773 >                wrint32(bw->flen-bw->fbmp, bw); /* correct bitmap length */
774          } else {
775                  wrbyte(0, bw); wrbyte(0, bw);   /* end of line marker */
776          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines