vfs: check userland buffers before reading them.
[haiku.git] / src / tools / translation / bmpinfo / bmpinfo.cpp
blobc5e7a516c01504ba50034e664e6da254179b515f
1 /*****************************************************************************/
2 // bmpinfo
3 // Written by Michael Wilber, OBOS Translation Kit Team
4 //
5 // Version:
6 //
7 // bmpinfo is a command line program for displaying information about
8 // BMP images.
9 //
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
13 // and are:
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 /*****************************************************************************/
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ByteOrder.h>
39 #include <Catalog.h>
40 #include <File.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
59 struct MSInfoHeader {
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)
81 void
82 print_bmp_info(BFile &file)
84 uint8 buf[40];
85 BMPFileHeader fh;
87 ssize_t size = 14;
88 if (file.Read(buf, size) != size) {
89 printf(B_TRANSLATE("Error: unable to read BMP file header\n"));
90 return;
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,
106 fh.fileSize);
107 printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"),
108 fh.reserved, 0);
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"));
115 return;
117 swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST);
119 if (headersize == sizeof(MSInfoHeader)) {
120 // MS format
121 MSInfoHeader msh;
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"));
125 return;
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"),
138 msh.planes);
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"),
143 msh.compression);
144 else if (msh.compression == BMP_RLE8_COMPRESS)
145 printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"),
146 msh.compression);
147 else if (msh.compression == BMP_RLE4_COMPRESS)
148 printf(B_TRANSLATE(" compression: RLE4 (%lu)\n"),
149 msh.compression);
150 else
151 printf(B_TRANSLATE(" compression: unknown (%lu)\n"),
152 msh.compression);
153 printf(B_TRANSLATE(" image size: 0x%.8lx (%lu)\n"), msh.imagesize,
154 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)) {
161 // OS/2 format
163 OS2InfoHeader os2;
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 "
167 "header\n"));
168 return;
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"),
177 os2.size, os2.size);
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"),
182 os2.bitsperpixel);
184 } else
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)
192 printf("\n");
194 if (argc == 1) {
195 printf(B_TRANSLATE("bmpinfo - reports information about a BMP image "
196 "file\n"));
197 printf(B_TRANSLATE("\nUsage:\n"));
198 printf(B_TRANSLATE("bmpinfo filename.bmp\n"));
200 else {
201 BFile file;
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]);
206 else {
207 printf(B_TRANSLATE("\nBMP image information for: %s\n"),
208 argv[i]);
209 print_bmp_info(file);
215 printf("\n");
217 return 0;