diff options
Diffstat (limited to 'converter')
-rw-r--r-- | converter/bmp.h | 50 | ||||
-rw-r--r-- | converter/other/bmptopnm.c | 88 |
2 files changed, 82 insertions, 56 deletions
diff --git a/converter/bmp.h b/converter/bmp.h index 8b2aa302..80e93fba 100644 --- a/converter/bmp.h +++ b/converter/bmp.h @@ -88,12 +88,30 @@ enum bmpClass {C_WIN=1, C_OS2=2}; static char const er_internal[] = "%s: internal error!"; /* Values of the "compression" field of the BMP info header */ -#define COMP_RGB 0 -#define COMP_RLE8 1 -#define COMP_RLE4 2 -#define COMP_BITFIELDS 3 -#define COMP_JPEG 4 -#define COMP_PNG 5 +typedef enum BMPCompType { + BMPCOMP_RGB = 0, + BMPCOMP_RLE8 = 1, + BMPCOMP_RLE4 = 2, + BMPCOMP_BITFIELDS = 3, + BMPCOMP_JPEG = 4, + BMPCOMP_PNG = 5 +} BMPCompType; + +static __inline__ const char * +BMPCompTypeName(BMPCompType const compression) { + + switch (compression) { + case BMPCOMP_RGB: return "none (RBG)"; + case BMPCOMP_RLE4: return "4 bit run-length coding"; + case BMPCOMP_RLE8: return "8 bit run-length coding"; + case BMPCOMP_BITFIELDS: return "none (bitfields)"; + case BMPCOMP_JPEG: return "JPEG (not supported)"; + case BMPCOMP_PNG: return "PNG (not supported)"; + } + return 0; /* Default compiler warning */ +} + + static __inline__ unsigned int BMPlenfileheader(enum bmpClass const class) { @@ -214,21 +232,21 @@ BMPoffbits(enum bmpClass const class, static __inline__ unsigned int -BMPlenfileGen(enum bmpClass const class, - unsigned int const bitcount, - unsigned int const cmapsize, - unsigned int const x, - unsigned int const y, - unsigned int const imageSize, - unsigned long int const compression) { +BMPlenfileGen(enum bmpClass const class, + unsigned int const bitcount, + unsigned int const cmapsize, + unsigned int const x, + unsigned int const y, + unsigned int const imageSize, + BMPCompType const compression) { /*---------------------------------------------------------------------------- Return the size of the BMP file in bytes. -----------------------------------------------------------------------------*/ unsigned int retval; switch (compression) { - case COMP_RGB: - case COMP_BITFIELDS: + case BMPCOMP_RGB: + case BMPCOMP_BITFIELDS: retval = BMPoffbits(class, bitcount, cmapsize) + BMPlenbits(class, bitcount, x, y); @@ -250,7 +268,7 @@ BMPlenfile(enum bmpClass const class, /*---------------------------------------------------------------------------- return the size of the BMP file in bytes; no compression -----------------------------------------------------------------------------*/ - return BMPlenfileGen(class, bitcount, cmapsize, x, y, 0, COMP_RGB); + return BMPlenfileGen(class, bitcount, cmapsize, x, y, 0, BMPCOMP_RGB); } #endif diff --git a/converter/other/bmptopnm.c b/converter/other/bmptopnm.c index 55608cc8..d4487f97 100644 --- a/converter/other/bmptopnm.c +++ b/converter/other/bmptopnm.c @@ -101,7 +101,7 @@ struct bmpInfoHeader { /* Size in bytes of the image data. We only reference this when the image is compressed. */ unsigned short cPlanes; - unsigned long int compression; + BMPCompType compression; struct pixelformat pixelformat; }; @@ -307,7 +307,7 @@ readOs2InfoHeader(FILE * const ifP, pm_error("Unrecognized bits per pixel in OS/2 BMP file header: %d", headerP->cBitCount); - headerP->compression = COMP_RGB; + headerP->compression = BMPCOMP_RGB; pm_message("OS/2 BMP, %dx%dx%d", headerP->cols, headerP->rows, headerP->cBitCount); @@ -320,26 +320,26 @@ validateCompression(unsigned long const compression, enum rowOrder const rowOrder, unsigned int const cBitCount) { - if (compression != COMP_RGB && compression != COMP_BITFIELDS && - compression != COMP_RLE4 && compression != COMP_RLE8 ) + if (compression != BMPCOMP_RGB && compression != BMPCOMP_BITFIELDS && + compression != BMPCOMP_RLE4 && compression != BMPCOMP_RLE8) pm_error("Input has unknown encoding. " "Compression type code = %ld. The only ones we know " "are RGB (%u), BITFIELDS (%u), " "RLE4 (%u), and RLE8 (%u)", - compression, COMP_RGB, COMP_BITFIELDS, - COMP_RLE4, COMP_RLE8); + compression, BMPCOMP_RGB, BMPCOMP_BITFIELDS, + BMPCOMP_RLE4, BMPCOMP_RLE8); - if ((compression == COMP_RLE4 || compression == COMP_RLE8) && + if ((compression == BMPCOMP_RLE4 || compression == BMPCOMP_RLE8) && rowOrder == TOPDOWN ) pm_error("Invalid BMP header. Claims image is top-down and also " "compressed, which is an impossible combination."); - if ( (compression == COMP_RLE4 && cBitCount !=4) || - (compression == COMP_RLE8 && cBitCount !=8) ) + if ((compression == BMPCOMP_RLE4 && cBitCount !=4 ) || + (compression == BMPCOMP_RLE8 && cBitCount !=8 )) pm_error("Invalid BMP header. " "Compression type (%s) disagrees with " "number of bits per pixel (%u).", - compression == COMP_RLE4 ? "RLE4" : "RLE8", + compression == BMPCOMP_RLE4 ? "RLE4" : "RLE8", cBitCount); } @@ -377,11 +377,11 @@ readWindowsBasic40ByteInfoHeader(FILE * const ifP, { unsigned long int const compression = GetLong(ifP); - headerP->bitFields = (compression == COMP_BITFIELDS); - validateCompression(compression, headerP->rowOrder, headerP->cBitCount); + headerP->bitFields = (compression == BMPCOMP_BITFIELDS); + headerP->compression = compression; } /* And read the rest of the junk in the 40 byte header */ @@ -973,12 +973,12 @@ readrowRLE(FILE * const ifP, unsigned int const row, unsigned int const cols, bool const lastrow, - unsigned long const compression, + BMPCompType const compression, unsigned char ** const BMPraster, unsigned int * const bytesReadP) { - bool const RLE4 = (compression == COMP_RLE4); - int const pixelsPerRowMargin = RLE4 ? cols % 2 : 0; + bool const rle4 = (compression == BMPCOMP_RLE4); + int const pixelsPerRowMargin = rle4 ? cols % 2 : 0; char const err_decode[] = "Error while decoding compressed BMP image. " @@ -996,17 +996,17 @@ readrowRLE(FILE * const ifP, totalBytesRead = 0; /* Initial value */ pixelsRead = 0; /* Initial value */ - while (TRUE) { + while (true) { unsigned int n; /* decompressed bytes already read; current write point */ unsigned int cnt; unsigned char code; - n = RLE4 ? (pixelsRead + 1) / 2 : pixelsRead; + n = rle4 ? (pixelsRead + 1) / 2 : pixelsRead; switch (readRLEcode(ifP, &cnt, &code)) { case ENC_MODE: { - unsigned int const byteCnt = RLE4 ? (cnt + 1) /2 : cnt; + unsigned int const byteCnt = rle4 ? (cnt + 1) /2 : cnt; unsigned int i; if (pixelsRead + cnt > cols + pixelsPerRowMargin) @@ -1016,7 +1016,7 @@ readrowRLE(FILE * const ifP, for (i = 0; i < byteCnt; ++i) BMPraster[row][n+i] = code; - if (RLE4 && pixelsRead % 2 == 1) + if (rle4 && pixelsRead % 2 == 1) /* previous read ended odd */ nibbleAlign(&BMPraster[row][n-1], cnt); @@ -1028,7 +1028,7 @@ readrowRLE(FILE * const ifP, unsigned int cmpBytesRead; /* compressed bytes read */ /* align read-end to 16 bit boundary */ unsigned int const bytesToRead = - RLE4 ? (cnt + 3) / 4 * 2 : (cnt + 1) / 2 * 2; + rle4 ? (cnt + 3) / 4 * 2 : (cnt + 1) / 2 * 2; if (pixelsRead + cnt > cols + pixelsPerRowMargin) pm_error(err_decode, "Too many pixels in absolute mode", @@ -1045,7 +1045,7 @@ readrowRLE(FILE * const ifP, pm_error("Error reading BMP raster. Errno=%d (%s)", errno, strerror(errno)); } - if (RLE4 && pixelsRead % 2 == 1) /* previous read ended odd */ + if (rle4 && pixelsRead % 2 == 1) /* previous read ended odd */ nibbleAlign(&BMPraster[row][n-1], cnt); pixelsRead += cnt; @@ -1101,13 +1101,24 @@ BMPreadraster(FILE * const ifP, unsigned int const rows, enum rowOrder const rowOrder, unsigned int const cBitCount, - unsigned long int const compression, + BMPCompType const compression, unsigned char *** const BMPrasterP, unsigned int * const bytesReadP) { +/*---------------------------------------------------------------------------- + Read the raster from the BMP file on *ifP (which is positioned to the + raster). The raster is 'rows' rows of 'cols' columns, 'cBitCount' bits per + pixel, with rows in order 'rowOrder'. + + Return the raster in a newly malloced 2-dimensional array and return + a pointer to that array as *BMPrasterP. + Leave the input file positioned immediately after the raster and return + as *bytesReadP the number of bytes we read from the file (i.e. the number + of bytes in the raster portion of the file). +-----------------------------------------------------------------------------*/ unsigned int const bytesPerRow = - (compression == COMP_RLE4) ? cols / 2 + 2 : - (compression == COMP_RLE8) ? cols + 1 : + (compression == BMPCOMP_RLE4) ? cols / 2 + 2 : + (compression == BMPCOMP_RLE8) ? cols + 1 : ((cols * cBitCount + 31) / 32) * 4; /* A BMP raster row is a multiple of 4 bytes, padded on the right with don't cares. @@ -1125,15 +1136,15 @@ BMPreadraster(FILE * const ifP, */ switch(compression){ - case COMP_RGB: - case COMP_BITFIELDS: { + case BMPCOMP_RGB: + case BMPCOMP_BITFIELDS: { unsigned int i; for (i = 0; i < rows; ++i) readrow(ifP, rowOrder == TOPDOWN ? i : rows - i - 1, bytesPerRow, BMPraster, bytesReadP); } break; - case COMP_RLE4: - case COMP_RLE8: { + case BMPCOMP_RLE4: + case BMPCOMP_RLE8: { unsigned int i; /* Read all rows except last */ for (i = 0; i < rows - 1; ++i){ @@ -1144,11 +1155,15 @@ BMPreadraster(FILE * const ifP, readrowRLE(ifP, rowOrder == TOPDOWN ? i : rows - i - 1, cols, TRUE, compression, BMPraster, bytesReadP); } break; - default: - pm_error("The BMP specifies a compression scheme we don't " - "recognize. Code= %lu", compression); + case BMPCOMP_JPEG: + pm_error("BMP file uses JPEG compression. We don't know how to " + "interpret that."); + break; + case BMPCOMP_PNG: + pm_error("BMP file uses PNG compression. We don't know how to " + "interpret that."); + break; } - *BMPrasterP = BMPraster; } @@ -1170,14 +1185,7 @@ reportHeader(struct bmpInfoHeader const header, header.rowOrder == BOTTOMUP ? "bottom up" : "top down"); pm_message(" Byte offset of raster within file: %u", offBits); pm_message(" Bits per pixel in raster: %u", header.cBitCount); - pm_message(" Compression: %s", - header.compression == COMP_RGB ? "none" : - header.compression == COMP_RLE4 ? "4 bit run-length coding" : - header.compression == COMP_RLE8 ? "8 bit run-length coding" : - header.compression == COMP_BITFIELDS ? "none" : - header.compression == COMP_JPEG ? "JPEG (not supported)" : - header.compression == COMP_PNG ? "PNG (not supported)" : - "???"); + pm_message(" Compression: %s", BMPCompTypeName(header.compression)); pm_message(" Colors in color map: %u", header.cmapsize); } |