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