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.11 by schorsch, Wed Jul 28 00:17:58 2004 UTC vs.
Revision 2.20 by greg, Wed Jan 23 19:13:55 2019 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
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 */
20 > /* Get corresponding error message */
21   const char *
22   BMPerrorMessage(int ec)
23   {
# Line 36 | 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 69 | 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 84 | 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 98 | 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 112 | 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 124 | 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 136 | 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   {
148          BMPReader       *br;
149 <        uint32          bmPos, hdrSiz;
150 <        int             palLen;
146 <        int     magic[2];               /* check magic number */
149 >        uint32          bmPos, hdrSiz, palSiz;
150 >        int             magic[2];               /* check magic number */
151  
152          if (cget == NULL)
153                  return NULL;
# Line 184 | Line 188 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
188          br->hdr->hRes = rdint32(br);            /* horizontal resolution */
189          br->hdr->vRes = rdint32(br);            /* vertical resolution */
190          br->hdr->nColors = rdint32(br);         /* # colors used */
191 +        if (!br->hdr->nColors && br->hdr->bpp <= 8)
192 +                br->hdr->nColors = 1<<br->hdr->bpp;
193          br->hdr->impColors = rdint32(br);       /* # important colors */
194          if (br->hdr->impColors < 0)
195                  goto err;                       /* catch premature EOF */
196          if (!BMPheaderOK(br->hdr))
197                  goto err;
198 <        palLen = BMPpalLen(br->hdr);
199 <        if (br->hdr->bpp <= 8) {                /* normalize color counts */
200 <                if (br->hdr->nColors <= 0)
195 <                        br->hdr->nColors = palLen;
196 <                if (br->hdr->impColors <= 0)
197 <                        br->hdr->impColors = br->hdr->nColors;
198 <        }
198 >        palSiz = sizeof(RGBquad)*br->hdr->nColors;
199 >        if (br->hdr->impColors <= 0)
200 >                br->hdr->impColors = br->hdr->nColors;
201                                                  /* extend header */
202 <        if (bmPos < hdrSiz + sizeof(RGBquad)*palLen)
202 >        if (bmPos < hdrSiz + palSiz)
203                  goto err;
204 <        br->hdr->infoSiz = bmPos - (hdrSiz + sizeof(RGBquad)*palLen);
205 <        if (palLen > 0 || br->hdr->infoSiz > 0) {
204 >        br->hdr->infoSiz = bmPos - (hdrSiz + palSiz);
205 >        if (br->hdr->nColors > 0 || br->hdr->infoSiz > 0) {
206                  br->hdr = (BMPHeader *)realloc((void *)br->hdr,
207                                          sizeof(BMPHeader) +
208 <                                        sizeof(RGBquad)*palLen +
207 <                                        br->hdr->infoSiz);
208 >                                        palSiz + br->hdr->infoSiz);
209                  if (br->hdr == NULL)
210                          goto err;
211          }
# Line 213 | Line 214 | BMPopenReader(int (*cget)(void *), int (*seek)(uint32,
214                  BMPbitField(br->hdr)[0] = (uint32)rdint32(br);
215                  BMPbitField(br->hdr)[1] = (uint32)rdint32(br);
216                  BMPbitField(br->hdr)[2] = (uint32)rdint32(br);
217 <        } else if (rdbytes((char *)br->hdr->palette,
217 <                        sizeof(RGBquad)*palLen, br) != BIR_OK)
217 >        } else if (rdbytes((char *)br->hdr->palette, palSiz, br) != BIR_OK)
218                  goto err;
219                                                  /* read add'l information */
220          if (rdbytes(BMPinfo(br->hdr), br->hdr->infoSiz, br) != BIR_OK)
# Line 248 | Line 248 | err:
248          return NULL;
249   }
250  
251 < /* determine if image is grayscale */
251 > /* Determine if image is grayscale */
252   int
253   BMPisGrayscale(const BMPHeader *hdr)
254   {
# Line 259 | Line 259 | BMPisGrayscale(const BMPHeader *hdr)
259                  return -1;
260          if (hdr->bpp > 8)               /* assume they had a reason for it */
261                  return 0;
262 <        for (rgbp = hdr->palette, n = hdr->nColors; n-- > 0; rgbp++)
263 <                if (((rgbp->r != rgbp->g) | (rgbp->g != rgbp->b)))
262 >        for (rgbp = hdr->palette, n = hdr->impColors; n-- > 0; rgbp++)
263 >                if ((rgbp->r != rgbp->g) | (rgbp->g != rgbp->b))
264                          return 0;
265          return 1;                       /* all colors neutral in map */
266   }
267  
268 < /* read and decode next BMP scanline */
268 > /* Read and decode next BMP scanline */
269   int
270   BMPreadScanline(BMPReader *br)
271   {
# Line 300 | Line 300 | BMPreadScanline(BMPReader *br)
300           * is it specified what we should assume for missing pixels.  This
301           * is undoubtedly the most brain-dead format I've ever encountered.
302           */
303 <        sp = br->scanline;
303 >        sp = (int8 *)br->scanline;
304          n = br->hdr->width;
305          if (br->hdr->compr == BI_RLE4)
306                  n = (n + 1) >> 1;
# Line 364 | Line 364 | BMPreadScanline(BMPReader *br)
364          return BIR_OK;
365   }
366  
367 < /* read a specific scanline */
367 > /* Read a specific scanline */
368   int
369   BMPseekScanline(int y, BMPReader *br)
370   {
# Line 407 | Line 407 | BMPseekScanline(int y, BMPReader *br)
407          return BIR_OK;
408   }
409  
410 < /* get ith pixel from last scanline */
410 > /* Get ith pixel from last scanline */
411   RGBquad
412   BMPdecodePixel(int i, const BMPReader *br)
413   {
# Line 453 | Line 453 | BMPdecodePixel(int i, const BMPReader *br)
453          case 8:
454                  return br->hdr->palette[br->scanline[i]];
455          case 1:
456 <                return br->hdr->palette[br->scanline[i>>3]>>((7-i)&7) & 1];
456 >                return br->hdr->palette[br->scanline[i>>3]>>(7-(i&7)) & 1];
457          case 4:
458                  return br->hdr->palette[br->scanline[i>>1]>>(i&1?4:0) & 0xf];
459          case 16:
# Line 471 | Line 471 | BMPdecodePixel(int i, const BMPReader *br)
471          return black;                           /* should never happen */
472   }
473  
474 < /* free BMP reader resources */
474 > /* Free BMP reader resources */
475   void
476   BMPfreeReader(BMPReader *br)
477   {
# Line 508 | Line 508 | stdio_fseek(uint32 pos, void *p)
508          return fseek((FILE *)p, (long)pos, 0);
509   }
510  
511 < /* allocate uncompressed (24-bit) RGB header */
511 > /* Allocate uncompressed (24-bit) RGB header */
512   BMPHeader *
513   BMPtruecolorHeader(int xr, int yr, int infolen)
514   {
# Line 531 | Line 531 | BMPtruecolorHeader(int xr, int yr, int infolen)
531          return hdr;
532   }
533  
534 < /* allocate color-mapped header (defaults to minimal grayscale) */
534 > /* Allocate color-mapped header (defaults to minimal grayscale) */
535   BMPHeader *
536   BMPmappedHeader(int xr, int yr, int infolen, int ncolors)
537   {
# Line 549 | Line 549 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
549          else
550                  return NULL;
551          hdr = (BMPHeader *)malloc(sizeof(BMPHeader) +
552 <                                        sizeof(RGBquad)*(1<<n) -
552 >                                        sizeof(RGBquad)*((size_t)1<<n) -
553                                          sizeof(hdr->palette) +
554                                          infolen);
555          if (hdr == NULL)
# Line 563 | Line 563 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
563          hdr->nColors = ncolors;
564          hdr->impColors = 0;                     /* says all colors important */
565          hdr->infoSiz = infolen;
566 <        memset((void *)hdr->palette, 0, sizeof(RGBquad)*(1<<n) + infolen);
566 >        memset((void *)hdr->palette, 0, sizeof(RGBquad)*((size_t)1<<n) + infolen);
567          for (n = ncolors; n--; )
568                  hdr->palette[n].r = hdr->palette[n].g =
569                          hdr->palette[n].b = n*255/(ncolors-1);
# Line 576 | Line 576 | BMPmappedHeader(int xr, int yr, int infolen, int ncolo
576                                          ((bw)->flen = (bw)->fpos) : \
577                                          (bw)->fpos )
578  
579 < /* write out a string of bytes */
579 > /* Write out a string of bytes */
580   static void
581   wrbytes(char *bp, uint32 n, BMPWriter *bw)
582   {
# Line 584 | Line 584 | wrbytes(char *bp, uint32 n, BMPWriter *bw)
584                  wrbyte(*bp++, bw);
585   }
586  
587 < /* write 32-bit integer in littlendian order */
587 > /* Write 32-bit integer in littlendian order */
588   static void
589   wrint32(int32 i, BMPWriter *bw)
590   {
# Line 594 | Line 594 | wrint32(int32 i, BMPWriter *bw)
594          wrbyte(i>>24 & 0xff, bw);
595   }
596  
597 < /* write 16-bit unsigned integer in littlendian order */
597 > /* Write 16-bit unsigned integer in littlendian order */
598   static void
599   wruint16(uint16 ui, BMPWriter *bw)
600   {
# Line 602 | Line 602 | wruint16(uint16 ui, BMPWriter *bw)
602          wrbyte(ui>>8 & 0xff, bw);
603   }
604  
605 < /* seek to the specified file position, returning 0 (BIR_OK) on success */
605 > /* Seek to the specified file position, returning 0 (BIR_OK) on success */
606   static int
607   wrseek(uint32 pos, BMPWriter *bw)
608   {
# Line 618 | Line 618 | wrseek(uint32 pos, BMPWriter *bw)
618          return BIR_OK;
619   }
620  
621 < /* open BMP stream for writing */
621 > /* Open BMP stream for writing */
622   BMPWriter *
623   BMPopenWriter(void (*cput)(int, void *), int (*seek)(uint32, void *),
624                          void *c_data, BMPHeader *hdr)
# Line 640 | Line 640 | BMPopenWriter(void (*cput)(int, void *), int (*seek)(u
640          hdrSiz = 2 + 6*4 + 2*2 + 6*4;
641          if (hdr->compr == BI_BITFIELDS)
642                  hdrSiz += sizeof(uint32)*3;
643 <        palSiz = sizeof(RGBquad)*BMPpalLen(hdr);
643 >        palSiz = sizeof(RGBquad)*hdr->nColors;
644          scanSiz = getScanSiz(hdr);
645          bmSiz = hdr->height*scanSiz;            /* wrong if compressed */
646                                                  /* initialize writer */
# Line 691 | Line 691 | BMPopenWriter(void (*cput)(int, void *), int (*seek)(u
691          return bw;
692   }
693  
694 < /* find position of next run of 5 or more identical bytes, or 255 if none */
694 > /* Find position of next run of 5 or more identical bytes, or 255 if none */
695   static int
696   findNextRun(const int8 *bp, int len)
697   {
# Line 708 | Line 708 | findNextRun(const int8 *bp, int len)
708          return pos;                             /* didn't find any */
709   }
710                                  
711 < /* write the current scanline */
711 > /* Write the current scanline */
712   int
713   BMPwriteScanline(BMPWriter *bw)
714   {
# Line 736 | Line 736 | BMPwriteScanline(BMPWriter *bw)
736           * (0x0000) except for the last, which ends in a bitmap break
737           * (0x0001).  We don't support RLE4 at all; it's too awkward.
738           */
739 <        sp = bw->scanline;
739 >        sp = (const int8 *)bw->scanline;
740          n = bw->hdr->width;
741          while (n > 0) {
742                  int     cnt, val;
# Line 753 | Line 753 | BMPwriteScanline(BMPWriter *bw)
753                  }
754                  if (n <= 0)                     /* was that it? */
755                          break;
756 <                val = *sp;                      /* output run */
757 <                for (cnt = 1; --n && cnt < 255; cnt++)
758 <                        if (*++sp != val)
756 >                val = *sp++;                    /* output run */
757 >                for (cnt = 1; --n && cnt < 255; cnt++, sp++)
758 >                        if (*sp != val)
759                                  break;
760                  wrbyte(cnt, bw);
761                  wrbyte(val, bw);
# Line 775 | Line 775 | BMPwriteScanline(BMPWriter *bw)
775          return BIR_OK;
776   }
777  
778 < /* free BMP writer resources */
778 > /* Free BMP writer resources */
779   void
780   BMPfreeWriter(BMPWriter *bw)
781   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines