diff --git a/src/tools/translation/bmpinfo/Jamfile b/src/tools/translation/bmpinfo/Jamfile new file mode 100644 index 0000000000..290d5efc9a --- /dev/null +++ b/src/tools/translation/bmpinfo/Jamfile @@ -0,0 +1,4 @@ +SubDir OBOS_TOP src tools translation bmpinfo ; + +BinCommand bmpinfo : bmpinfo.cpp : be ; + diff --git a/src/tools/translation/bmpinfo/bmpinfo.cpp b/src/tools/translation/bmpinfo/bmpinfo.cpp new file mode 100644 index 0000000000..4bc53eaec3 --- /dev/null +++ b/src/tools/translation/bmpinfo/bmpinfo.cpp @@ -0,0 +1,198 @@ +/*****************************************************************************/ +// bmpinfo +// Written by Michael Wilber, OBOS Translation Kit Team +// +// Version: +// +// bmpinfo is a command line program for displaying information about +// BMP images. +// +// +// This application and all source files used in its construction, except +// where noted, are licensed under the MIT License, and have been written +// and are: +// +// Copyright (c) 2003 OpenBeOS Project +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#define BMP_NO_COMPRESS 0 +#define BMP_RLE8_COMPRESS 1 +#define BMP_RLE4_COMPRESS 2 + +struct BMPFileHeader { + // for both MS and OS/2 BMP formats + uint16 magic; // = 'BM' + uint32 fileSize; // file size in bytes + uint32 reserved; // equals 0 + uint32 dataOffset; // file offset to actual image +}; + +struct MSInfoHeader { + uint32 size; // size of this struct (40) + uint32 width; // bitmap width + uint32 height; // bitmap height + uint16 planes; // number of planes, always 1? + uint16 bitsperpixel; // bits per pixel, (1,4,8,16 or 24) + uint32 compression; // type of compression + uint32 imagesize; // size of image data if compressed + uint32 xpixperm; // horizontal pixels per meter + uint32 ypixperm; // vertical pixels per meter + uint32 colorsused; // number of actually used colors + uint32 colorsimportant; // number of important colors, zero = all +}; + +struct OS2InfoHeader { + uint32 size; // size of this struct (12) + uint16 width; // bitmap width + uint16 height; // bitmap height + uint16 planes; // number of planes, always 1? + uint16 bitsperpixel; // bits per pixel, (1,4,8,16 or 24) +}; + +void +print_bmp_info(BFile &file) +{ + uint8 buf[40]; + BMPFileHeader fh; + + ssize_t size = 14; + if (file.Read(buf, size) != size) { + printf("Error: unable to read BMP file header\n"); + return; + } + + // convert fileHeader to host byte order + memcpy(&fh.magic, buf, 2); + memcpy(&fh.fileSize, buf + 2, 4); + memcpy(&fh.reserved, buf + 6, 4); + memcpy(&fh.dataOffset, buf + 10, 4); + swap_data(B_UINT16_TYPE, &fh.magic, sizeof(uint16), + B_SWAP_BENDIAN_TO_HOST); + swap_data(B_UINT32_TYPE, (reinterpret_cast (&fh)) + 2, + 12, B_SWAP_LENDIAN_TO_HOST); + + printf("\nFile Header:\n"); + printf(" magic: 0x%.4lx (should be: 0x424d)\n", fh.magic); + printf(" file size: 0x%.8lx (%u)\n", fh.fileSize, fh.fileSize); + printf(" reserved: 0x%.8lx (should be: 0x%.8lx)\n", fh.reserved, 0); + printf("data offset: 0x%.8lx (%u) (should be: >= 54 for MS format " + "and >= 26 for OS/2 format)\n", fh.dataOffset, fh.dataOffset); + + uint32 headersize = 0; + if (file.Read(&headersize, 4) != 4) { + printf("Error: unable to read info header size\n"); + return; + } + swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST); + + if (headersize == sizeof(MSInfoHeader)) { + // MS format + MSInfoHeader msh; + msh.size = headersize; + if (file.Read(reinterpret_cast (&msh) + 4, 36) != 36) { + printf("Error: unable to read entire MS info header\n"); + return; + } + + // convert msheader to host byte order + swap_data(B_UINT32_TYPE, reinterpret_cast (&msh) + 4, 36, + B_SWAP_LENDIAN_TO_HOST); + + printf("\nMS Info Header:\n"); + printf(" header size: 0x%.8lx (%u) (should be: 40)\n", msh.size, msh.size); + printf(" width: %u\n", msh.width); + printf(" height: %u\n", msh.height); + printf(" planes: %u (should be: 1)\n", msh.planes); + printf(" bits per pixel: %u (should be: 1,4,8,16,24 or 32)\n", msh.bitsperpixel); + printf(" compression: %s (%u)\n", + ((msh.compression == BMP_NO_COMPRESS) ? ("none") : + ((msh.compression == BMP_RLE8_COMPRESS) ? ("RLE 8") : + ((msh.compression == BMP_RLE4_COMPRESS) ? ("RLE 4") : + ("unknown")))), msh.compression); + printf(" image size: 0x%.8lx (%u)\n", msh.imagesize, msh.imagesize); + printf(" x pixels/meter: %u\n", msh.xpixperm); + printf(" y pixels/meter: %u\n", msh.ypixperm); + printf(" colors used: %u\n", msh.colorsused); + printf("colors important: %u\n", msh.colorsimportant); + + } else if (headersize == sizeof(OS2InfoHeader)) { + // OS/2 format + + OS2InfoHeader os2; + os2.size = headersize; + if (file.Read(reinterpret_cast (&os2) + 4, 8) != 8) { + printf("Error: unable to read entire OS/2 info header\n"); + return; + } + + // convert os2header to host byte order + swap_data(B_UINT32_TYPE, reinterpret_cast (&os2) + 4, 8, + B_SWAP_LENDIAN_TO_HOST); + + printf("\nOS/2 Info Header:\n"); + printf(" header size: 0x%.8lx (%u) (should be: 12)\n", os2.size, os2.size); + printf(" width: %u\n", os2.width); + printf(" height: %u\n", os2.height); + printf(" planes: %u (should be: 1)\n", os2.planes); + printf("bits per pixel: %u (should be: 1,4,8 or 24)\n", + os2.bitsperpixel); + + } else + printf("Error: info header size (%u) does not match MS or OS/2 " + "info header size\n", headersize); +} + +int +main(int argc, char **argv) +{ + printf("\n"); + + if (argc == 1) { + printf("bmpinfo - reports information about a BMP image file\n"); + printf("\nUsage:\n"); + printf("bmpinfo filename.bmp\n"); + } + else { + BFile file; + + for (int32 i = 1; i < argc; i++) { + if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) + printf("\nError opening %s\n", argv[i]); + else { + printf("\nBMP image information for: %s\n", argv[i]); + print_bmp_info(file); + } + } + + } + + printf("\n"); + + return 0; +} +