xref: /haiku/src/tools/translation/bitsinfo/bitsinfo.cpp (revision 7b3e89c0944ae1efa9a8fc66c7303874b7a344b2)
1 /*****************************************************************************/
2 // bitsinfo
3 // Written by Michael Wilber, Haiku Translation Kit Team
4 //
5 // Version:
6 //
7 // bitsinfo is a command line program for displaying text information about
8 // Be bitmap format ("bits") images.  The Be bitmap format is used by
9 // the Translation Kit as the intermediate format for converting images.
10 // To make "bits" images, you can use the "translate" command line program or
11 // the BBitmapTranslator (available: http://www.bebits.com/app/647).
12 //
13 // This application and all source files used in its construction, except
14 // where noted, are licensed under the MIT License, and have been written
15 // and are:
16 //
17 // Copyright (c) 2003 Haiku Project
18 //
19 // Permission is hereby granted, free of charge, to any person obtaining a
20 // copy of this software and associated documentation files (the "Software"),
21 // to deal in the Software without restriction, including without limitation
22 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
23 // and/or sell copies of the Software, and to permit persons to whom the
24 // Software is furnished to do so, subject to the following conditions:
25 //
26 // The above copyright notice and this permission notice shall be included
27 // in all copies or substantial portions of the Software.
28 //
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 // DEALINGS IN THE SOFTWARE.
36 /*****************************************************************************/
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <ByteOrder.h>
41 #include <Catalog.h>
42 #include <File.h>
43 #include <TranslatorFormats.h>
44 #include <StorageDefs.h>
45 
46 #undef B_TRANSLATION_CONTEXT
47 #define B_TRANSLATION_CONTEXT "bitsinfo"
48 
49 struct ColorSpaceName {
50 	color_space id;
51 	const char *name;
52 };
53 #define COLORSPACENAME(id) {id, #id}
54 
55 const char *kpixels = "-pixels";
56 
57 void
58 PrintBitsInfo(const char *filepath, bool bdumppixels)
59 {
60 	BFile file(filepath, B_READ_ONLY);
61 
62 	if (file.InitCheck() == B_OK) {
63 		TranslatorBitmap header;
64 		memset(&header, 0, sizeof(TranslatorBitmap));
65 
66 		// read in the rest of the header
67 		ssize_t size = sizeof(TranslatorBitmap);
68 		if (file.Read(reinterpret_cast<uint8 *> (&header), size) != size) {
69 			printf(B_TRANSLATE("\nError: Unable to read the Be bitmap "
70 				"header.\n"));
71 			return;
72 		}
73 		if (!bdumppixels)
74 			// I don't need the file anymore
75 			file.Unset();
76 
77 		// convert to host byte order
78 		if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap),
79 			B_SWAP_BENDIAN_TO_HOST) != B_OK) {
80 			printf(B_TRANSLATE("\nError: Unable to swap byte order\n"));
81 			return;
82 		}
83 
84 		printf(B_TRANSLATE("\nBe bitmap (\"bits\") header for: %s\n\n"),
85 			filepath);
86 
87 		const uint32 kbitsmagic = 0x62697473UL;
88 			// in ASCII, this number looks like "bits"
89 		if (header.magic == kbitsmagic)
90 			printf(B_TRANSLATE("magic number: 0x%.8lx (valid)\n"),
91 				header.magic);
92 		else
93 			printf(B_TRANSLATE("magic number: 0x%.8lx (INVALID, should be: "
94 				"0x%.8lx)\n"), header.magic, kbitsmagic);
95 		printf(B_TRANSLATE("bounds: (%f, %f, %f, %f)\n"),
96 			header.bounds.left, header.bounds.top,
97 			header.bounds.right, header.bounds.bottom);
98 		printf(B_TRANSLATE("dimensions: %d x %d\n"),
99 			static_cast<int>(header.bounds.Width() + 1),
100 			static_cast<int>(header.bounds.Height() + 1));
101 
102 		printf(B_TRANSLATE("bytes per row: %u\n"),
103 			static_cast<unsigned int>(header.rowBytes));
104 
105 		// print out colorspace if it matches an item in the list
106 		ColorSpaceName colorspaces[] = {
107 			COLORSPACENAME(B_NO_COLOR_SPACE),
108 			COLORSPACENAME(B_RGB32),
109 			COLORSPACENAME(B_RGBA32),
110 			COLORSPACENAME(B_RGB24),
111 			COLORSPACENAME(B_RGB16),
112 			COLORSPACENAME(B_RGB15),
113 			COLORSPACENAME(B_RGBA15),
114 			COLORSPACENAME(B_CMAP8),
115 			COLORSPACENAME(B_GRAY8),
116 			COLORSPACENAME(B_GRAY1),
117 			COLORSPACENAME(B_RGB32_BIG),
118 			COLORSPACENAME(B_RGBA32_BIG),
119 			COLORSPACENAME(B_RGB24_BIG),
120 			COLORSPACENAME(B_RGB16_BIG),
121 			COLORSPACENAME(B_RGB15_BIG),
122 			COLORSPACENAME(B_RGBA15_BIG),
123 			COLORSPACENAME(B_YCbCr422),
124 			COLORSPACENAME(B_YCbCr411),
125 			COLORSPACENAME(B_YCbCr444),
126 			COLORSPACENAME(B_YCbCr420),
127 			COLORSPACENAME(B_YUV422),
128 			COLORSPACENAME(B_YUV411),
129 			COLORSPACENAME(B_YUV444),
130 			COLORSPACENAME(B_YUV420),
131 			COLORSPACENAME(B_YUV9),
132 			COLORSPACENAME(B_YUV12),
133 			COLORSPACENAME(B_UVL24),
134 			COLORSPACENAME(B_UVL32),
135 			COLORSPACENAME(B_UVLA32),
136 			COLORSPACENAME(B_LAB24),
137 			COLORSPACENAME(B_LAB32),
138 			COLORSPACENAME(B_LABA32),
139 			COLORSPACENAME(B_HSI24),
140 			COLORSPACENAME(B_HSI32),
141 			COLORSPACENAME(B_HSIA32),
142 			COLORSPACENAME(B_HSV24),
143 			COLORSPACENAME(B_HSV32),
144 			COLORSPACENAME(B_HSVA32),
145 			COLORSPACENAME(B_HLS24),
146 			COLORSPACENAME(B_HLS32),
147 			COLORSPACENAME(B_HLSA32),
148 			COLORSPACENAME(B_CMY24),
149 			COLORSPACENAME(B_CMY32),
150 			COLORSPACENAME(B_CMYA32),
151 			COLORSPACENAME(B_CMYK32)
152 		};
153 		const int32 kncolorspaces =  sizeof(colorspaces) /
154 			sizeof(ColorSpaceName);
155 		int32 i;
156 		for (i = 0; i < kncolorspaces; i++) {
157 			if (header.colors == colorspaces[i].id) {
158 				printf(B_TRANSLATE("color space: %s\n"), colorspaces[i].name);
159 				break;
160 			}
161 		}
162 		if (i == kncolorspaces)
163 			printf(B_TRANSLATE("color space: Unknown (0x%.8lx)\n"),
164 				static_cast<unsigned long>(header.colors));
165 
166 		printf(B_TRANSLATE("data size: %u\n"),
167 			static_cast<unsigned int>(header.dataSize));
168 
169 		if (bdumppixels) {
170 			const char *components = NULL;
171 			int32 ncomponents = 0;
172 			switch (header.colors) {
173 				case B_RGB24:
174 					components = "BGR";
175 					ncomponents = 3;
176 					break;
177 				case B_RGB32:
178 					components = "BGR-";
179 					ncomponents = 4;
180 					break;
181 				case B_RGBA32:
182 					components = "BGRA";
183 					ncomponents = 4;
184 					break;
185 
186 				default:
187 					printf(B_TRANSLATE("Sorry, %s isn't supported yet"
188 						" for this color space\n"), kpixels);
189 					return;
190 			}
191 			uint8 *prow = new uint8[header.rowBytes];
192 			if (!prow) {
193 				printf(B_TRANSLATE("Error: Not enough memory for row "
194 					"buffer\n"));
195 				return;
196 			}
197 			ssize_t ret, n;
198 			uint32 totalbytes = 0;
199 			printf(B_TRANSLATE("pixel data (%s):\n"), components);
200 			while ((ret = file.Read(prow, header.rowBytes)) > 0) {
201 				n = 0;
202 				while (n < ret) {
203 					if (n && !(n % ncomponents))
204 						printf(" ");
205 					printf("%.2X", prow[n]);
206 					n++;
207 					totalbytes++;
208 					if (!(totalbytes % (uint32) ret))
209 						printf("\n\n");
210 				}
211 			}
212 		}
213 
214 	} else
215 		printf(B_TRANSLATE_COMMENT("Error opening %s\n",
216 			"file path is opening"), filepath);
217 }
218 
219 int
220 main(int argc, char **argv)
221 {
222 	if (argc == 1) {
223 		printf(B_TRANSLATE("\nbitsinfo - reports information about a Be "
224 			"bitmap (\"bits\") image\n"));
225 		printf(B_TRANSLATE("\nUsage:\n"));
226 		printf(B_TRANSLATE("bitsinfo [options] filename.bits\n\n"));
227 		printf(B_TRANSLATE("Options:\n\n"));
228 		printf(B_TRANSLATE("\t%s \t print RGB color for each pixel\n"),
229 			kpixels);
230 	}
231 	else {
232 		int32 first = 1;
233 		bool bdumppixels = false;
234 		if (strcmp(argv[1], kpixels) == 0) {
235 			bdumppixels = true;
236 			first = 2;
237 		}
238 
239 		for (int32 i = first; i < argc; i++)
240 			PrintBitsInfo(argv[i], bdumppixels);
241 	}
242 
243 	printf("\n");
244 
245 	return 0;
246 }
247 
248