| 1 | 
greg | 
2.9 | 
/* RCSid $Id: bmpfile.h,v 2.8 2017/09/05 18:41:22 greg Exp $ */ | 
| 2 | 
greg | 
2.1 | 
/* | 
| 3 | 
  | 
  | 
 *  Windows and OS/2 BMP file support | 
| 4 | 
  | 
  | 
 */ | 
| 5 | 
  | 
  | 
 | 
| 6 | 
  | 
  | 
#ifndef _RAD_BMPFILE_H_ | 
| 7 | 
  | 
  | 
#define _RAD_BMPFILE_H_ | 
| 8 | 
  | 
  | 
 | 
| 9 | 
greg | 
2.6 | 
#include "tiff.h"                       /* needed for int32, etc. */ | 
| 10 | 
greg | 
2.1 | 
 | 
| 11 | 
  | 
  | 
#ifdef __cplusplus | 
| 12 | 
  | 
  | 
extern "C" { | 
| 13 | 
  | 
  | 
#endif | 
| 14 | 
  | 
  | 
 | 
| 15 | 
  | 
  | 
                                        /* compression modes */ | 
| 16 | 
  | 
  | 
#define BI_UNCOMPR              0               /* no compression */ | 
| 17 | 
  | 
  | 
#define BI_RLE8                 1               /* runlength on bytes */ | 
| 18 | 
  | 
  | 
#define BI_RLE4                 2               /* runlength on half-bytes */ | 
| 19 | 
  | 
  | 
#define BI_BITFIELDS            3               /* uncompressed w/ bitfields */ | 
| 20 | 
  | 
  | 
 | 
| 21 | 
  | 
  | 
/* A Color table entry */ | 
| 22 | 
  | 
  | 
typedef struct { | 
| 23 | 
  | 
  | 
        uint8           b, g, r;        /* blue, green, & red bytes */ | 
| 24 | 
  | 
  | 
        uint8           padding;        /* padding to 32-bit boundary */ | 
| 25 | 
  | 
  | 
} RGBquad; | 
| 26 | 
  | 
  | 
 | 
| 27 | 
  | 
  | 
/* Allocated BMP header data */ | 
| 28 | 
  | 
  | 
typedef struct { | 
| 29 | 
greg | 
2.3 | 
        /* the following fields may be altered before the open call */ | 
| 30 | 
greg | 
2.1 | 
        int             yIsDown;        /* scanlines proceed downward? */ | 
| 31 | 
  | 
  | 
        int32           hRes;           /* horizontal resolution pixels/meter */ | 
| 32 | 
  | 
  | 
        int32           vRes;           /* vertical resolution pixels/meter */ | 
| 33 | 
  | 
  | 
        int             nColors;        /* total color palette size */ | 
| 34 | 
greg | 
2.8 | 
        int             impColors;      /* number of colors actually used */ | 
| 35 | 
greg | 
2.3 | 
        int             compr;          /* compression */ | 
| 36 | 
greg | 
2.1 | 
        int32           width;          /* bitmap width (pixels) */ | 
| 37 | 
  | 
  | 
        int32           height;         /* bitmap height (pixels) */ | 
| 38 | 
greg | 
2.3 | 
        /* the following fields must not be altered after allocation */ | 
| 39 | 
greg | 
2.9 | 
        int             bpp;            /* bits per pixel (1,4,8,16,24,32) */ | 
| 40 | 
greg | 
2.1 | 
        uint32          infoSiz;        /* info buffer size (bytes) */ | 
| 41 | 
greg | 
2.3 | 
        /* but the color table should be filled by writer before open call */ | 
| 42 | 
greg | 
2.8 | 
        RGBquad         palette[3];     /* color palette (extends struct) */ | 
| 43 | 
greg | 
2.1 | 
} BMPHeader; | 
| 44 | 
greg | 
2.2 | 
                                 | 
| 45 | 
  | 
  | 
                                        /* access to bit field triple */ | 
| 46 | 
greg | 
2.8 | 
#define BMPbitField(h)  ((uint32 *)(h)->palette) | 
| 47 | 
greg | 
2.1 | 
 | 
| 48 | 
  | 
  | 
                                        /* info buffer access */ | 
| 49 | 
greg | 
2.8 | 
#define BMPinfo(h)      ((char *)((h)->palette + (h)->nColors)) | 
| 50 | 
greg | 
2.1 | 
 | 
| 51 | 
  | 
  | 
                                        /* function return values */ | 
| 52 | 
  | 
  | 
#define BIR_OK                  0               /* all is well */ | 
| 53 | 
  | 
  | 
#define BIR_EOF                 (-1)            /* reached end of file */ | 
| 54 | 
  | 
  | 
#define BIR_TRUNCATED           1               /* unexpected EOF */ | 
| 55 | 
  | 
  | 
#define BIR_UNSUPPORTED         2               /* unsupported encoding */ | 
| 56 | 
greg | 
2.2 | 
#define BIR_RLERROR             3               /* RLE error */ | 
| 57 | 
  | 
  | 
#define BIR_SEEKERR             4               /* could not seek */ | 
| 58 | 
greg | 
2.1 | 
 | 
| 59 | 
  | 
  | 
/* A BMP reader structure */ | 
| 60 | 
  | 
  | 
typedef struct BMPReader { | 
| 61 | 
  | 
  | 
        /* members in this structure should be considered read-only */ | 
| 62 | 
greg | 
2.8 | 
        uint8           *scanline;      /* unpacked scanline data */ | 
| 63 | 
greg | 
2.1 | 
        int             yscan;          /* last scanline read */ | 
| 64 | 
greg | 
2.8 | 
        BMPHeader       *hdr;           /* pointer to allocated header */ | 
| 65 | 
greg | 
2.1 | 
        uint32          fpos;           /* current file position */ | 
| 66 | 
  | 
  | 
                                        /* get character callback */ | 
| 67 | 
  | 
  | 
        int             (*cget)(void *); | 
| 68 | 
  | 
  | 
                                        /* absolute seek callback (or NULL) */ | 
| 69 | 
  | 
  | 
        int             (*seek)(uint32, void *); | 
| 70 | 
  | 
  | 
        void            *c_data;        /* client's opaque data */ | 
| 71 | 
greg | 
2.8 | 
        uint32          scanpos[1];     /* recorded scanline position(s) */ | 
| 72 | 
greg | 
2.1 | 
} BMPReader; | 
| 73 | 
  | 
  | 
 | 
| 74 | 
  | 
  | 
/* A BMP writer structure */ | 
| 75 | 
  | 
  | 
typedef struct { | 
| 76 | 
  | 
  | 
        /* the scanline data is filled in by caller before each write */ | 
| 77 | 
greg | 
2.8 | 
        uint8           *scanline;      /* caller-prepared scanline data */ | 
| 78 | 
greg | 
2.3 | 
        /* modify yscan only if seek is defined & data is uncompressed */ | 
| 79 | 
greg | 
2.1 | 
        int             yscan;          /* scanline for next write */ | 
| 80 | 
greg | 
2.3 | 
        /* the following fields should not be altered directly */ | 
| 81 | 
greg | 
2.8 | 
        BMPHeader       *hdr;           /* allocated header */ | 
| 82 | 
greg | 
2.1 | 
        uint32          fbmp;           /* beginning of bitmap data */ | 
| 83 | 
  | 
  | 
        uint32          fpos;           /* current file position */ | 
| 84 | 
  | 
  | 
        uint32          flen;           /* last character written */ | 
| 85 | 
  | 
  | 
                                        /* put character callback */ | 
| 86 | 
  | 
  | 
        void            (*cput)(int, void *); | 
| 87 | 
  | 
  | 
                                        /* absolute seek callback (or NULL) */ | 
| 88 | 
  | 
  | 
        int             (*seek)(uint32, void *); | 
| 89 | 
  | 
  | 
        void            *c_data;        /* client's opaque data */ | 
| 90 | 
  | 
  | 
} BMPWriter; | 
| 91 | 
  | 
  | 
 | 
| 92 | 
  | 
  | 
                                        /* open BMP stream for reading */ | 
| 93 | 
greg | 
2.8 | 
extern BMPReader        *BMPopenReader(int (*cget)(void *), | 
| 94 | 
greg | 
2.1 | 
                                int (*seek)(uint32, void *), void *c_data); | 
| 95 | 
  | 
  | 
 | 
| 96 | 
  | 
  | 
                                        /* determine if image is grayscale */ | 
| 97 | 
greg | 
2.7 | 
extern int              BMPisGrayscale(const BMPHeader *hdr); | 
| 98 | 
greg | 
2.1 | 
 | 
| 99 | 
  | 
  | 
                                        /* read next BMP scanline */ | 
| 100 | 
greg | 
2.7 | 
extern int              BMPreadScanline(BMPReader *br); | 
| 101 | 
greg | 
2.1 | 
 | 
| 102 | 
  | 
  | 
                                        /* read a specific scanline */ | 
| 103 | 
greg | 
2.7 | 
extern int              BMPseekScanline(int y, BMPReader *br); | 
| 104 | 
greg | 
2.1 | 
 | 
| 105 | 
  | 
  | 
                                        /* get ith pixel from last scanline */ | 
| 106 | 
greg | 
2.7 | 
extern RGBquad          BMPdecodePixel(int i, const BMPReader *br); | 
| 107 | 
greg | 
2.1 | 
 | 
| 108 | 
  | 
  | 
                                        /* free BMP reader resources */ | 
| 109 | 
greg | 
2.7 | 
extern void             BMPfreeReader(BMPReader *br); | 
| 110 | 
greg | 
2.1 | 
 | 
| 111 | 
  | 
  | 
                                        /* allocate uncompressed RGB header */ | 
| 112 | 
greg | 
2.8 | 
extern BMPHeader        *BMPtruecolorHeader(int xr, int yr, int infolen); | 
| 113 | 
greg | 
2.1 | 
 | 
| 114 | 
  | 
  | 
                                        /* allocate color-mapped header */ | 
| 115 | 
greg | 
2.8 | 
extern BMPHeader        *BMPmappedHeader(int xr, int yr, int infolen, int ncolors); | 
| 116 | 
greg | 
2.1 | 
 | 
| 117 | 
  | 
  | 
                                        /* open BMP stream for writing */ | 
| 118 | 
greg | 
2.7 | 
extern BMPWriter        *BMPopenWriter(void (*cput)(int, void *), | 
| 119 | 
greg | 
2.1 | 
                                int (*seek)(uint32, void *), void *c_data, | 
| 120 | 
  | 
  | 
                                        BMPHeader *hdr); | 
| 121 | 
  | 
  | 
                                 | 
| 122 | 
  | 
  | 
                                        /* write the prepared scanline */ | 
| 123 | 
greg | 
2.7 | 
extern int              BMPwriteScanline(BMPWriter *bw); | 
| 124 | 
greg | 
2.1 | 
 | 
| 125 | 
  | 
  | 
                                        /* free BMP writer resources */ | 
| 126 | 
greg | 
2.7 | 
extern void             BMPfreeWriter(BMPWriter *bw); | 
| 127 | 
greg | 
2.1 | 
 | 
| 128 | 
  | 
  | 
                                        /* get corresponding error message */ | 
| 129 | 
greg | 
2.8 | 
extern const char       *BMPerrorMessage(int ec); | 
| 130 | 
greg | 
2.1 | 
 | 
| 131 | 
  | 
  | 
                                        /* stdio callback functions */ | 
| 132 | 
greg | 
2.7 | 
extern int              stdio_getc(void *p); | 
| 133 | 
  | 
  | 
extern void             stdio_putc(int c, void *p); | 
| 134 | 
  | 
  | 
extern int              stdio_fseek(uint32 pos, void *p); | 
| 135 | 
greg | 
2.1 | 
 | 
| 136 | 
  | 
  | 
                                        /* open stdio input stream */ | 
| 137 | 
greg | 
2.8 | 
#define BMPopenInputStream(fp)  BMPopenReader(&stdio_getc, NULL, (void *)fp) | 
| 138 | 
greg | 
2.1 | 
 | 
| 139 | 
  | 
  | 
                                        /* open input file */ | 
| 140 | 
greg | 
2.8 | 
#define BMPopenInputFile(fn)    BMPopenReader(&stdio_getc, &stdio_fseek, \ | 
| 141 | 
greg | 
2.5 | 
                                        (void *)fopen(fn, "rb")) | 
| 142 | 
greg | 
2.1 | 
 | 
| 143 | 
  | 
  | 
                                        /* close stdio input file or stream */ | 
| 144 | 
greg | 
2.8 | 
#define BMPcloseInput(br)       ( fclose((FILE *)(br)->c_data), \ | 
| 145 | 
greg | 
2.1 | 
                                        BMPfreeReader(br) ) | 
| 146 | 
  | 
  | 
 | 
| 147 | 
  | 
  | 
                                        /* open stdio output stream */ | 
| 148 | 
  | 
  | 
#define BMPopenOutputStream(fp,hdr) \ | 
| 149 | 
  | 
  | 
                        BMPopenWriter(&stdio_putc, NULL, (void *)fp, hdr) | 
| 150 | 
  | 
  | 
 | 
| 151 | 
  | 
  | 
                                        /* open stdio output file */ | 
| 152 | 
  | 
  | 
#define BMPopenOutputFile(fn,hdr) \ | 
| 153 | 
  | 
  | 
                        BMPopenWriter(&stdio_putc, &stdio_fseek, \ | 
| 154 | 
greg | 
2.5 | 
                                        (void *)fopen(fn, "wb"), hdr) | 
| 155 | 
greg | 
2.1 | 
 | 
| 156 | 
  | 
  | 
                                        /* close stdio output file or stream */ | 
| 157 | 
greg | 
2.8 | 
#define BMPcloseOutput(bw)      ( fclose((FILE *)(bw)->c_data), \ | 
| 158 | 
greg | 
2.1 | 
                                        BMPfreeWriter(bw) ) | 
| 159 | 
  | 
  | 
 | 
| 160 | 
  | 
  | 
#ifdef __cplusplus | 
| 161 | 
  | 
  | 
} | 
| 162 | 
  | 
  | 
#endif | 
| 163 | 
  | 
  | 
#endif  /* ! _RAD_BMPFILE_H_ */ |