1 /*****************************************************************************/
3 // Written by Michael Wilber, OBOS Translation Kit Team
7 // bmpinfo is a command line program for displaying information about
11 // This application and all source files used in its construction, except
12 // where noted, are licensed under the MIT License, and have been written
15 // Copyright (c) 2003 OpenBeOS Project
17 // Permission is hereby granted, free of charge, to any person obtaining a
18 // copy of this software and associated documentation files (the "Software"),
19 // to deal in the Software without restriction, including without limitation
20 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 // and/or sell copies of the Software, and to permit persons to whom the
22 // Software is furnished to do so, subject to the following conditions:
24 // The above copyright notice and this permission notice shall be included
25 // in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 // DEALINGS IN THE SOFTWARE.
34 /*****************************************************************************/
38 #include <ByteOrder.h>
41 #include <TranslatorFormats.h>
42 #include <StorageDefs.h>
44 #undef B_TRANSLATE_CONTEXT
45 #define B_TRANSLATE_CONTEXT "bmpinfo"
47 #define BMP_NO_COMPRESS 0
48 #define BMP_RLE8_COMPRESS 1
49 #define BMP_RLE4_COMPRESS 2
51 struct BMPFileHeader
{
52 // for both MS and OS/2 BMP formats
53 uint16 magic
; // = 'BM'
54 uint32 fileSize
; // file size in bytes
55 uint32 reserved
; // equals 0
56 uint32 dataOffset
; // file offset to actual image
60 uint32 size
; // size of this struct (40)
61 uint32 width
; // bitmap width
62 uint32 height
; // bitmap height
63 uint16 planes
; // number of planes, always 1?
64 uint16 bitsperpixel
; // bits per pixel, (1,4,8,16 or 24)
65 uint32 compression
; // type of compression
66 uint32 imagesize
; // size of image data if compressed
67 uint32 xpixperm
; // horizontal pixels per meter
68 uint32 ypixperm
; // vertical pixels per meter
69 uint32 colorsused
; // number of actually used colors
70 uint32 colorsimportant
; // number of important colors, zero = all
73 struct OS2InfoHeader
{
74 uint32 size
; // size of this struct (12)
75 uint16 width
; // bitmap width
76 uint16 height
; // bitmap height
77 uint16 planes
; // number of planes, always 1?
78 uint16 bitsperpixel
; // bits per pixel, (1,4,8,16 or 24)
82 print_bmp_info(BFile
&file
)
88 if (file
.Read(buf
, size
) != size
) {
89 printf(B_TRANSLATE("Error: unable to read BMP file header\n"));
93 // convert fileHeader to host byte order
94 memcpy(&fh
.magic
, buf
, 2);
95 memcpy(&fh
.fileSize
, buf
+ 2, 4);
96 memcpy(&fh
.reserved
, buf
+ 6, 4);
97 memcpy(&fh
.dataOffset
, buf
+ 10, 4);
98 swap_data(B_UINT16_TYPE
, &fh
.magic
, sizeof(uint16
),
99 B_SWAP_BENDIAN_TO_HOST
);
100 swap_data(B_UINT32_TYPE
, (reinterpret_cast<uint8
*> (&fh
)) + 2,
101 12, B_SWAP_LENDIAN_TO_HOST
);
103 printf(B_TRANSLATE("\nFile Header:\n"));
104 printf(B_TRANSLATE(" magic: 0x%.4x (should be: 0x424d)\n"), fh
.magic
);
105 printf(B_TRANSLATE(" file size: 0x%.8lx (%lu)\n"), fh
.fileSize
,
107 printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"),
109 printf(B_TRANSLATE("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS "
110 "format and >= 26 for OS/2 format)\n"), fh
.dataOffset
, fh
.dataOffset
);
112 uint32 headersize
= 0;
113 if (file
.Read(&headersize
, 4) != 4) {
114 printf(B_TRANSLATE("Error: unable to read info header size\n"));
117 swap_data(B_UINT32_TYPE
, &headersize
, 4, B_SWAP_LENDIAN_TO_HOST
);
119 if (headersize
== sizeof(MSInfoHeader
)) {
122 msh
.size
= headersize
;
123 if (file
.Read(reinterpret_cast<uint8
*> (&msh
) + 4, 36) != 36) {
124 printf(B_TRANSLATE("Error: unable to read entire MS info header\n"));
128 // convert msheader to host byte order
129 swap_data(B_UINT32_TYPE
, reinterpret_cast<uint8
*> (&msh
) + 4, 36,
130 B_SWAP_LENDIAN_TO_HOST
);
132 printf(B_TRANSLATE("\nMS Info Header:\n"));
133 printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: "
134 "40)\n"), msh
.size
, msh
.size
);
135 printf(B_TRANSLATE(" width: %lu\n"), msh
.width
);
136 printf(B_TRANSLATE(" height: %lu\n"), msh
.height
);
137 printf(B_TRANSLATE(" planes: %u (should be: 1)\n"),
139 printf(B_TRANSLATE(" bits per pixel: %u (should be: 1,4,8,16,24 or "
140 "32)\n"), msh
.bitsperpixel
);
141 if (msh
.compression
== BMP_NO_COMPRESS
)
142 printf(B_TRANSLATE(" compression: none (%lu)\n"),
144 else if (msh
.compression
== BMP_RLE8_COMPRESS
)
145 printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"),
147 else if (msh
.compression
== BMP_RLE4_COMPRESS
)
148 printf(B_TRANSLATE(" compression: RLE4 (%lu)\n"),
151 printf(B_TRANSLATE(" compression: unknown (%lu)\n"),
153 printf(B_TRANSLATE(" image size: 0x%.8lx (%lu)\n"), msh
.imagesize
,
155 printf(B_TRANSLATE(" x pixels/meter: %lu\n"), msh
.xpixperm
);
156 printf(B_TRANSLATE(" y pixels/meter: %lu\n"), msh
.ypixperm
);
157 printf(B_TRANSLATE(" colors used: %lu\n"), msh
.colorsused
);
158 printf(B_TRANSLATE("colors important: %lu\n"), msh
.colorsimportant
);
160 } else if (headersize
== sizeof(OS2InfoHeader
)) {
164 os2
.size
= headersize
;
165 if (file
.Read(reinterpret_cast<uint8
*> (&os2
) + 4, 8) != 8) {
166 printf(B_TRANSLATE("Error: unable to read entire OS/2 info "
171 // convert os2header to host byte order
172 swap_data(B_UINT32_TYPE
, reinterpret_cast<uint8
*> (&os2
) + 4, 8,
173 B_SWAP_LENDIAN_TO_HOST
);
175 printf(B_TRANSLATE("\nOS/2 Info Header:\n"));
176 printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: 12)\n"),
178 printf(B_TRANSLATE(" width: %u\n"), os2
.width
);
179 printf(B_TRANSLATE(" height: %u\n"), os2
.height
);
180 printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), os2
.planes
);
181 printf(B_TRANSLATE("bits per pixel: %u (should be: 1,4,8 or 24)\n"),
185 printf(B_TRANSLATE("Error: info header size (%lu) does not match MS "
186 "or OS/2 info header size\n"), headersize
);
190 main(int argc
, char **argv
)
195 printf(B_TRANSLATE("bmpinfo - reports information about a BMP image "
197 printf(B_TRANSLATE("\nUsage:\n"));
198 printf(B_TRANSLATE("bmpinfo filename.bmp\n"));
203 for (int32 i
= 1; i
< argc
; i
++) {
204 if (file
.SetTo(argv
[i
], B_READ_ONLY
) != B_OK
)
205 printf(B_TRANSLATE("\nError opening %s\n"), argv
[i
]);
207 printf(B_TRANSLATE("\nBMP image information for: %s\n"),
209 print_bmp_info(file
);