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.13 by greg, Fri Mar 18 21:04:05 2005 UTC vs.
Revision 2.21 by greg, Mon Oct 4 23:04:59 2021 UTC

# Line 17 | Line 17 | static const char RCSid[] = "$Id$";
17   #define putc    putc_unlocked
18   #endif
19  
20 < /* get corresponding error message */
20 > /* Get corresponding error message */
21   const char *
22   BMPerrorMessage(int ec)
23   {
# Line 38 | Line 38 | BMPerrorMessage(int ec)
38          return "Unknown BMP error";
39   }
40  
41 < /* check than header is sensible */
41 > /* Check that header is sensible */
42   static int
43   BMPheaderOK(const BMPHeader *hdr)
44   {
# Line 89 | Line 89 | BMPheaderOK(const BMPHeader *hdr)
89                                          /* get next byte from reader */
90   #define rdbyte(c,br)    ((br)->fpos += (c=(*(br)->cget)((br)->c_data))!=EOF, c)
91  
92 < /* read n bytes */
92 > /* Read n bytes */
93   static int
94   rdbytes(char *bp, uint32 n, BMPReader *br)
95   {
# Line 103 | Line 103 | rdbytes(char *bp, uint32 n, BMPReader *br)
103          return BIR_OK;
104   }
105  
106 < /* read 32-bit integer in littlendian order */
106 > /* Read 32-bit integer in littlendian order */
107   static int32
108   rdint32(BMPReader *br)
109   {
# Line 117 | Line 117 | rdint32(BMPReader *br)
117          return i;                       /* -1 on EOF */
118   }
119  
120 < /* read 16-bit unsigned integer in littlendian order */
120 > /* Read 16-bit unsigned integer in littlendian order */
121   static int
122   rduint16(BMPReader *br)
123   {
# Line 129 | Line 129 | rduint16(BMPReader *br)
129          return i;                       /* -1 on EOF */
130   }
131  
132 < /* seek on reader or return 0 (BIR_OK) on success */
132 > /* Seek on reader or return 0 (BIR_OK) on success */
133   static int
134   rdseek(uint32 pos, BMPReader *br)
135   {
# Line 141 | Line 141 | rdseek(uint32 pos, BMPReader *br)
141          return BIR_OK;
142   }
143  
144 < /* open BMP stream for reading and get first scanline */
144 > /* Open BMP stream for reading and get first scanline */
145   BMPReader *
146   BMPopenReader(int (*cget)(void *), int (*seek)(uint32, void *), void *c_data)
147   {
# Line 151 | Line 151 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
151  
152          if (cget == NULL)
153                  return NULL;
154 +        if (cget == &stdio_getc && c_data == NULL)
155 +                return NULL;                    /* stdio error condition */
156          magic[0] = (*cget)(c_data);
157          if (magic[0] != 'B')
158                  return NULL;
# Line 188 | Line 190 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
190          br->hdr->hRes = rdint32(br);            /* horizontal resolution */
191          br->hdr->vRes = rdint32(br);            /* vertical resolution */
192          br->hdr->nColors = rdint32(br);         /* # colors used */
193 +        if (!br->hdr->nColors && br->hdr->bpp <= 8)
194 +                br->hdr->nColors = 1<<br->hdr->bpp;
195          br->hdr->impColors = rdint32(br);       /* # important colors */
196          if (br->hdr->impColors < 0)
197                  goto err;                       /* catch premature EOF */
# Line 246 | Line 250 | err:
250          return NULL;
251   }
252  
253 < /* determine if image is grayscale */
253 > /* Determine if image is grayscale */
254   int
255   BMPisGrayscale(const BMPHeader *hdr)
256   {
# Line 257 | 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->nColors; n-- > 0; rgbp++)
265 <                if (((rgbp->r != rgbp->g) | (rgbp->g != rgbp->b)))
264 >        for (rgbp = hdr->palette, n = hdr->impColors; n-- > 0; rgbp++)
265 >                if ((rgbp->r != rgbp->g) | (rgbp->g != rgbp->b))
266                          return 0;
267          return 1;                       /* all colors neutral in map */
268   }
269  
270 < /* read and decode next BMP scanline */
270 > /* Read and decode next BMP scanline */
271   int
272   BMPreadScanline(BMPReader *br)
273   {
# Line 298 | Line 302 | BMPreadScanline(BMPReader *br)
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;
305 >        sp = (int8 *)br->scanline;
306          n = br->hdr->width;
307          if (br->hdr->compr == BI_RLE4)
308                  n = (n + 1) >> 1;
# Line 362 | Line 366 | BMPreadScanline(BMPReader *br)
366          return BIR_OK;
367   }
368  
369 < /* read a specific scanline */
369 > /* Read a specific scanline */
370   int
371   BMPseekScanline(int y, BMPReader *br)
372   {
# Line 405 | Line 409 | BMPseekScanline(int y, BMPReader *br)
409          return BIR_OK;
410   }
411  
412 < /* get ith pixel from last scanline */
412 > /* Get ith pixel from last scanline */
413   RGBquad
414   BMPdecodePixel(int i, const BMPReader *br)
415   {
# Line 451 | Line 455 | BMPdecodePixel(int i, const BMPReader *br)
455          case 8:
456                  return br->hdr->palette[br->scanline[i]];
457          case 1:
458 <                return br->hdr->palette[br->scanline[i>>3]>>((7-i)&7) & 1];
458 >                return br->hdr->palette[br->scanline[i>>3]>>(7-(i&7)) & 1];
459          case 4:
460                  return br->hdr->palette[br->scanline[i>>1]>>(i&1?4:0) & 0xf];
461          case 16:
# Line 469 | Line 473 | BMPdecodePixel(int i, const BMPReader *br)
473          return black;                           /* should never happen */
474   }
475  
476 < /* free BMP reader resources */
476 > /* Free BMP reader resources */
477   void
478   BMPfreeReader(BMPReader *br)
479   {
# Line 506 | Line 510 | stdio_fseek(uint32 pos, void *p)
510          return fseek((FILE *)p, (long)pos, 0);
511   }
512  
513 < /* allocate uncompressed (24-bit) RGB header */
513 > /* Allocate uncompressed (24-bit) RGB header */
514   BMPHeader *
515   BMPtruecolorHeader(int xr, int yr, int infolen)
516   {
# Line 529 | Line 533 | BMPtruecolorHeader(int xr, int yr, int infolen)
533          return hdr;
534   }
535  
536 < /* allocate color-mapped header (defaults to minimal grayscale) */
536 > /* Allocate color-mapped header (defaults to minimal grayscale) */
537   BMPHeader *
538   BMPmappedHeader(int xr, int yr, int infolen, int ncolors)
539   {
# Line 547 | Line 551 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
551          else
552                  return NULL;
553          hdr = (BMPHeader *)malloc(sizeof(BMPHeader) +
554 <                                        sizeof(RGBquad)*(1<<n) -
554 >                                        sizeof(RGBquad)*((size_t)1<<n) -
555                                          sizeof(hdr->palette) +
556                                          infolen);
557          if (hdr == NULL)
# Line 561 | Line 565 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
565          hdr->nColors = ncolors;
566          hdr->impColors = 0;                     /* says all colors important */
567          hdr->infoSiz = infolen;
568 <        memset((void *)hdr->palette, 0, sizeof(RGBquad)*(1<<n) + infolen);
568 >        memset((void *)hdr->palette, 0, sizeof(RGBquad)*((size_t)1<<n) + infolen);
569          for (n = ncolors; n--; )
570                  hdr->palette[n].r = hdr->palette[n].g =
571                          hdr->palette[n].b = n*255/(ncolors-1);
# Line 574 | Line 578 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
578                                          ((bw)->flen = (bw)->fpos) : \
579                                          (bw)->fpos )
580  
581 < /* write out a string of bytes */
581 > /* Write out a string of bytes */
582   static void
583   wrbytes(char *bp, uint32 n, BMPWriter *bw)
584   {
# Line 582 | Line 586 | wrbytes(char *bp, uint32 n, BMPWriter *bw)
586                  wrbyte(*bp++, bw);
587   }
588  
589 < /* write 32-bit integer in littlendian order */
589 > /* Write 32-bit integer in littlendian order */
590   static void
591   wrint32(int32 i, BMPWriter *bw)
592   {
# Line 592 | Line 596 | wrint32(int32 i, BMPWriter *bw)
596          wrbyte(i>>24 & 0xff, bw);
597   }
598  
599 < /* write 16-bit unsigned integer in littlendian order */
599 > /* Write 16-bit unsigned integer in littlendian order */
600   static void
601   wruint16(uint16 ui, BMPWriter *bw)
602   {
# Line 600 | Line 604 | wruint16(uint16 ui, BMPWriter *bw)
604          wrbyte(ui>>8 & 0xff, bw);
605   }
606  
607 < /* seek to the specified file position, returning 0 (BIR_OK) on success */
607 > /* Seek to the specified file position, returning 0 (BIR_OK) on success */
608   static int
609   wrseek(uint32 pos, BMPWriter *bw)
610   {
# Line 616 | Line 620 | wrseek(uint32 pos, BMPWriter *bw)
620          return BIR_OK;
621   }
622  
623 < /* open BMP stream for writing */
623 > /* Open BMP stream for writing */
624   BMPWriter *
625   BMPopenWriter(void (*cput)(int, void *), int (*seek)(uint32, void *),
626                          void *c_data, BMPHeader *hdr)
# Line 626 | Line 630 | BMPopenWriter(void (*cput)(int, void *), int (*seek)(u
630                                                  /* check arguments */
631          if (cput == NULL)
632                  return NULL;
633 +        if (cput == &stdio_putc && c_data == NULL)
634 +                return NULL;                    /* stdio error condition */
635          if (!BMPheaderOK(hdr))
636                  return NULL;
637          if ((hdr->bpp == 16) | (hdr->compr == BI_RLE4))
# Line 689 | Line 695 | BMPopenWriter(void (*cput)(int, void *), int (*seek)(u
695          return bw;
696   }
697  
698 < /* find position of next run of 5 or more identical bytes, or 255 if none */
698 > /* Find position of next run of 5 or more identical bytes, or 255 if none */
699   static int
700   findNextRun(const int8 *bp, int len)
701   {
# Line 706 | Line 712 | findNextRun(const int8 *bp, int len)
712          return pos;                             /* didn't find any */
713   }
714                                  
715 < /* write the current scanline */
715 > /* Write the current scanline */
716   int
717   BMPwriteScanline(BMPWriter *bw)
718   {
# Line 734 | Line 740 | BMPwriteScanline(BMPWriter *bw)
740           * (0x0000) except for the last, which ends in a bitmap break
741           * (0x0001).  We don't support RLE4 at all; it's too awkward.
742           */
743 <        sp = bw->scanline;
743 >        sp = (const int8 *)bw->scanline;
744          n = bw->hdr->width;
745          while (n > 0) {
746                  int     cnt, val;
# Line 751 | Line 757 | BMPwriteScanline(BMPWriter *bw)
757                  }
758                  if (n <= 0)                     /* was that it? */
759                          break;
760 <                val = *sp;                      /* output run */
761 <                for (cnt = 1; --n && cnt < 255; cnt++)
762 <                        if (*++sp != val)
760 >                val = *sp++;                    /* output run */
761 >                for (cnt = 1; --n && cnt < 255; cnt++, sp++)
762 >                        if (*sp != val)
763                                  break;
764                  wrbyte(cnt, bw);
765                  wrbyte(val, bw);
# Line 773 | Line 779 | BMPwriteScanline(BMPWriter *bw)
779          return BIR_OK;
780   }
781  
782 < /* free BMP writer resources */
782 > /* Free BMP writer resources */
783   void
784   BMPfreeWriter(BMPWriter *bw)
785   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines