//============================================================================== // bxdump.cpp // Classes and functions to read and write Microsoft Windows bitmap (BMP) // graphic image files. // // Acknowledgements // Derived from source code written by David R. Tribble, Jan 1992. // // Copyright ©2008 by David R. Tribble, all rights reserved. // Permission is granted to any person or entity except those designated // by the United States Department of State as a terrorist, or terrorist // government or agency, to use and distribute this source code provided // that the original copyright notice remains present and unaltered. //============================================================================== // Identification static char REV[] = "@(#)drt/bmp/bxdump.cpp $Revision: 1.3 $$Date: 2008/04/29 02:18:38 $"; // System includes #include #define sys_iso646_h 1 #include #define sys_stddef_h 1 #include #define sys_stdio_h 1 // Local includes #include "bmpdefs.h" #include "bmpfile.hpp" //------------------------------------------------------------------------------ // ::hexbuf() // Converts raw bytes into a readable hexadecimal digit string. // // @param buf // Buffer to write the output string into. // // @param d // Array of data bytes to convert. // // @param len // Number of data bytes to convert. // // @return // Pointer 'buf'. //------------------------------------------------------------------------------ static const char * hexbuf(char *buf, const void *d, int len) { int i; char * sp; // Convert d[0..len-1] into a hex string for (sp = buf, i = 0; i < len; i++, sp += 3) ::sprintf(sp, "%02X ", ((const unsigned char *)d)[i]); for ( ; i < 5; i++, sp += 3) ::sprintf(sp, " "); sp[-1] = '\0'; return buf; } //------------------------------------------------------------------------------ // ::compression_name() // Convert a BMP compression type into its name. // // @param type // BMP compression type, one of the BMP_CMP_XXX values. // // @return // Pointer to a static string. //------------------------------------------------------------------------------ static const char * compression_name(uint32_t type) { switch (type) { case BMP_CMP_NONE: return "none"; case BMP_CMP_RLE8: return "RLE-8"; case BMP_CMP_RLE4: return "RLE-4"; default: return "unknown"; } } //------------------------------------------------------------------------------ // DrtBmpFile::dump_header() // Print the contents of a BMP file header. // // @param out // File to print the header information to. // // @param hdr // BMP file header to print. // // @return // Zero, or -1 on error. // // @since // 1.1, 2008-04-27 //------------------------------------------------------------------------------ /*static*/ int DrtBmpFile::dump_header(FILE *out, const struct bmp_header *hdr) { #if BMP_HEADER_VS != 1 #error struct bmp_header has changed #endif struct os2_bmp_header * os2; char buf[20+1]; // Check args if (out == NULL) return 0; if (hdr == NULL) return -1; // Print BMP header info ::fprintf(out, " %s id %04X\n", hexbuf(buf, &hdr->id, sizeof(hdr->id)), hdr->id); ::fprintf(out, " %s filesize %ld (%06lXh) bytes\n", hexbuf(buf, &hdr->filesize, sizeof(hdr->filesize)), (long)hdr->filesize, (long)hdr->filesize); ::fprintf(out, " %s reserved %02X %02X %02X %02X\n", hexbuf(buf, &hdr->r[0], sizeof(hdr->r)), hdr->r[0], hdr->r[1], hdr->r[2], hdr->r[3]); ::fprintf(out, " %s headersize %lu bytes\n", hexbuf(buf, &hdr->headersize, sizeof(hdr->headersize)), (unsigned long)hdr->headersize); if (hdr->infoSize <= 12) { // Print OS/2 BMP header info ::fprintf(out, " %s infoSize %lu bytes\n", hexbuf(buf, &hdr->infoSize, sizeof(os2->infoSize)), (unsigned long)hdr->infoSize); ::fprintf(out, " %s width %lu x\n", hexbuf(buf, &hdr->width, sizeof(os2->width)), (unsigned long)hdr->width); ::fprintf(out, " %s depth %lu y\n", hexbuf(buf, &hdr->depth, sizeof(os2->depth)), (unsigned long)hdr->depth); ::fprintf(out, " %s biPlanes %u\n", hexbuf(buf, &hdr->biPlanes, sizeof(os2->biPlanes)), hdr->biPlanes); ::fprintf(out, " %s bits %u, %s colors\n", hexbuf(buf, &hdr->bits, sizeof(os2->bits)), hdr->bits, (hdr->bits == 1 ? "2" : hdr->bits == 2 ? "4" : hdr->bits == 4 ? "16" : hdr->bits == 8 ? "256" : hdr->bits == 24 ? "16M" : "?")); } else { // Print Windows BMP header info ::fprintf(out, " %s infoSize %lu bytes\n", hexbuf(buf, &hdr->infoSize, sizeof(hdr->infoSize)), (unsigned long)hdr->infoSize); ::fprintf(out, " %s width %lu x\n", hexbuf(buf, &hdr->width, sizeof(hdr->width)), (unsigned long)hdr->width); ::fprintf(out, " %s depth %lu y\n", hexbuf(buf, &hdr->depth, sizeof(hdr->depth)), (unsigned long)hdr->depth); ::fprintf(out, " %s biPlanes %u\n", hexbuf(buf, &hdr->biPlanes, sizeof(hdr->biPlanes)), hdr->biPlanes); ::fprintf(out, " %s bits %u, %s colors\n", hexbuf(buf, &hdr->bits, sizeof(hdr->bits)), hdr->bits, (hdr->bits == 1 ? "2" : hdr->bits == 2 ? "4" : hdr->bits == 4 ? "16" : hdr->bits == 8 ? "256" : hdr->bits == 24 ? "16M" : "?")); ::fprintf(out, " %s biCompression %lu, %s\n", hexbuf(buf, &hdr->biCompression, sizeof(hdr->biCompression)), (unsigned long)hdr->biCompression, compression_name(hdr->biCompression)); ::fprintf(out, " %s biSizeImage %lu (%06lXh) bytes\n", hexbuf(buf, &hdr->biSizeImage, sizeof(hdr->biSizeImage)), (unsigned long)hdr->biSizeImage, (unsigned long)hdr->biSizeImage); ::fprintf(out, " %s biXPelsPerMeter %lu, %ld dpi\n", hexbuf(buf, &hdr->biXPelsPerMeter, sizeof(hdr->biXPelsPerMeter)), (unsigned long)hdr->biXPelsPerMeter, (hdr->biXPelsPerMeter*100L + 3937/2) / 3937); ::fprintf(out, " %s biYPelsPerMeter %lu, %ld dpi\n", hexbuf(buf, &hdr->biYPelsPerMeter, sizeof(hdr->biYPelsPerMeter)), (unsigned long)hdr->biYPelsPerMeter, (hdr->biYPelsPerMeter*100L + 3937/2) / 3937); ::fprintf(out, " %s biClrUsed %lu%s\n", hexbuf(buf, &hdr->biClrUsed, sizeof(hdr->biClrUsed)), (unsigned long)hdr->biClrUsed, (hdr->biClrUsed == 0 ? ", none" : " colors")); ::fprintf(out, " %s biClrImportant %lu%s\n", hexbuf(buf, &hdr->biClrImportant, sizeof(hdr->biClrImportant)), (unsigned long)hdr->biClrImportant, (hdr->biClrImportant == 0 ? ", none" : " colors")); } return 0; } //------------------------------------------------------------------------------ // DrtBmpFile::dump_header() // Print the contents of the BMP file header. // // @param out // File to print the header information to. // // @return // Zero, or -1 on error. // // @since // 1.2, 2008-04-28 //------------------------------------------------------------------------------ int DrtBmpFile::dump_header(FILE *out) { #if BMP_HEADER_VS != 1 #error struct bmp_header has changed #endif // Dump the contents of the BMP header return dump_header(out, &m_hdr); } //------------------------------------------------------------------------------ // DrtBmpFile::dump_palette() // Print the contents of an RGB color table. // // @param out // File to print the header information to. // // @param tab // RGB color table to print. // // @param sz // Size of the color table. // // @return // Zero, or -1 on error. // // @since // 1.1, 2008-04-27 //------------------------------------------------------------------------------ /*static*/ int DrtBmpFile::dump_palette(FILE *out, const struct bmp_rgb tab[], int sz) { unsigned i, j; // Check args if (out == NULL) return 0; if (tab == NULL) return -1; if (sz == 0) return 0; // Dump the color map table if (sz < 16) { for (i = 0; i < sz; i++) ::fprintf(out, " %02X[%02X:%02X:%02X:%02X]\n", i, tab[i].r, tab[i].g, tab[i].b, tab[i].a); } else { for (i = 0; i < sz/4; i++) { for (j = 0; j < sz; j += sz/4) ::fprintf(out, " %02X[%02X:%02X:%02X:%02X]", i+j, tab[i+j].r, tab[i+j].g, tab[i+j].b, tab[i+j].a); ::fprintf(out, "\n"); } } return 0; } //------------------------------------------------------------------------------ // DrtBmpFile::dump_palette() // Print the contents of the RGB color table. // // @param out // File to print the header information to. // // @return // Zero, or -1 on error. // // @since // 1.2, 2008-04-28 //------------------------------------------------------------------------------ int DrtBmpFile::dump_palette(FILE *out) { // Dump the color map table return dump_palette(out, m_map, m_ncols); } // End bxdump.cpp