1 /*****************************************************************************/ 2 // tgainfo 3 // Written by Michael Wilber, OBOS Translation Kit Team 4 // 5 // Version: 6 // 7 // tgainfo is a command line program for displaying information about 8 // TGA images. 9 // 10 // 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: 14 // 15 // Copyright (c) 2003 OpenBeOS Project 16 // 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: 23 // 24 // The above copyright notice and this permission notice shall be included 25 // in all copies or substantial portions of the Software. 26 // 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 <File.h> 40 #include <TranslatorFormats.h> 41 42 #define max(x,y) ((x > y) ? x : y) 43 #define DATA_BUFFER_SIZE 64 44 45 struct TGAFileHeader { 46 uint8 idlength; 47 // Number of bytes in the Image ID field 48 uint8 colormaptype; 49 uint8 imagetype; 50 }; 51 52 #define TGA_NO_COLORMAP 0 53 #define TGA_COLORMAP 1 54 55 #define TGA_NO_IMAGE_DATA 0 56 57 #define TGA_NOCOMP_COLORMAP 1 58 #define TGA_NOCOMP_TRUECOLOR 2 59 #define TGA_NOCOMP_BW 3 60 #define TGA_RLE_COLORMAP 9 61 #define TGA_RLE_TRUECOLOR 10 62 #define TGA_RLE_BW 11 63 64 // Information about the color map (palette). These bytes are 65 // always present, but are zero if no color map is present 66 struct TGAColorMapSpec { 67 uint16 firstentry; // first useful entry in the color map 68 uint16 length; // number of color map entries 69 uint8 entrysize; // number of bits per entry 70 }; 71 72 struct TGAImageSpec { 73 uint16 xorigin; 74 uint16 yorigin; 75 uint16 width; 76 uint16 height; 77 uint8 depth; 78 uint8 descriptor; 79 }; 80 81 #define TGA_ORIGIN_VERT_BIT 0x20 82 #define TGA_ORIGIN_BOTTOM 0 83 #define TGA_ORIGIN_TOP 1 84 85 #define TGA_ORIGIN_HORZ_BIT 0x10 86 #define TGA_ORIGIN_LEFT 0 87 #define TGA_ORIGIN_RIGHT 1 88 89 #define TGA_DESC_BITS76 0xc0 90 #define TGA_DESC_ALPHABITS 0x0f 91 92 #define TGA_HEADERS_SIZE 18 93 #define TGA_FTR_LEN 26 94 95 const char * 96 colormaptype(uint8 n) 97 { 98 switch (n) { 99 case 0: return "No colormap"; 100 case 1: return "colormap"; 101 } 102 return "unknown"; 103 } 104 105 const char * 106 imagetype(uint8 n) 107 { 108 switch (n) { 109 case 0: return "No Image Data"; 110 case 1: return "colormap"; 111 case 2: return "true color"; 112 case 3: return "grayscale"; 113 case 9: return "RLE colormap"; 114 case 10: return "RLE true color"; 115 case 11: return "RLE grayscale"; 116 } 117 return "unknown"; 118 } 119 120 void 121 print_tga_info(BFile &file) 122 { 123 uint8 buf[TGA_HEADERS_SIZE]; 124 125 // read in TGA headers 126 ssize_t size = TGA_HEADERS_SIZE; 127 if (size > 0 && file.Read(buf, size) != size) { 128 printf("Error: unable to read all TGA headers\n"); 129 return; 130 } 131 132 // TGA file header 133 TGAFileHeader fh; 134 fh.idlength = buf[0]; 135 fh.colormaptype = buf[1]; 136 fh.imagetype = buf[2]; 137 138 printf("\nFile Header:\n"); 139 printf(" id length: %d\n", fh.idlength); 140 141 printf("colormap type: %d (%s)\n", fh.colormaptype, 142 colormaptype(fh.colormaptype)); 143 printf(" image type: %d (%s)\n", fh.imagetype, imagetype(fh.imagetype)); 144 145 146 // TGA color map spec 147 TGAColorMapSpec mapspec; 148 memcpy(&mapspec.firstentry, buf + 3, 2); 149 mapspec.firstentry = B_LENDIAN_TO_HOST_INT16(mapspec.firstentry); 150 memcpy(&mapspec.length, buf + 5, 2); 151 mapspec.length = B_LENDIAN_TO_HOST_INT16(mapspec.length); 152 mapspec.entrysize = buf[7]; 153 154 printf("\nColormap Spec:\n"); 155 printf("first entry: %d\n", mapspec.firstentry); 156 printf(" length: %d\n", mapspec.length); 157 printf(" entry size: %d\n", mapspec.entrysize); 158 159 160 // TGA image spec 161 TGAImageSpec imagespec; 162 memcpy(&imagespec.xorigin, buf + 8, 2); 163 imagespec.xorigin = B_LENDIAN_TO_HOST_INT16(imagespec.xorigin); 164 165 memcpy(&imagespec.yorigin, buf + 10, 2); 166 imagespec.yorigin = B_LENDIAN_TO_HOST_INT16(imagespec.yorigin); 167 168 memcpy(&imagespec.width, buf + 12, 2); 169 imagespec.width = B_LENDIAN_TO_HOST_INT16(imagespec.width); 170 171 memcpy(&imagespec.height, buf + 14, 2); 172 imagespec.height = B_LENDIAN_TO_HOST_INT16(imagespec.height); 173 174 imagespec.depth = buf[16]; 175 imagespec.descriptor = buf[17]; 176 177 printf("\nImage Spec:\n"); 178 printf(" x origin: %d\n", imagespec.xorigin); 179 printf(" y origin: %d\n", imagespec.yorigin); 180 printf(" width: %d\n", imagespec.width); 181 printf(" height: %d\n", imagespec.height); 182 printf(" depth: %d\n", imagespec.depth); 183 printf("descriptor: 0x%.2lx\n", imagespec.descriptor); 184 printf("\talpha (attr): %d\n", 185 imagespec.descriptor & TGA_DESC_ALPHABITS); 186 printf("\t origin: %d (%s %s)\n", 187 imagespec.descriptor & (TGA_ORIGIN_VERT_BIT | TGA_ORIGIN_HORZ_BIT), 188 ((imagespec.descriptor & TGA_ORIGIN_VERT_BIT) ? "top" : "bottom"), 189 ((imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) ? "right" : "left")); 190 printf("\t bits 7 & 6: %d\n", imagespec.descriptor & TGA_DESC_BITS76); 191 192 193 // Optional TGA Footer 194 off_t filesize = 0; 195 if (file.GetSize(&filesize) == B_OK) { 196 197 char tgafooter[TGA_FTR_LEN + 1] = { 0 }; 198 if (file.ReadAt(filesize - TGA_FTR_LEN, tgafooter, TGA_FTR_LEN) == TGA_FTR_LEN) { 199 200 if (strcmp(tgafooter + 8, "TRUEVISION-XFILE.") == 0) { 201 202 uint32 extoffset = 0, devoffset = 0; 203 memcpy(&extoffset, tgafooter, 4); 204 memcpy(&devoffset, tgafooter + 4, 4); 205 extoffset = B_LENDIAN_TO_HOST_INT32(extoffset); 206 devoffset = B_LENDIAN_TO_HOST_INT32(devoffset); 207 208 printf("\nTGA Footer:\n"); 209 printf("extension offset: 0x%.8lx (%d)\n", extoffset, extoffset); 210 printf("developer offset: 0x%.8lx (%d)\n", devoffset, devoffset); 211 printf("signature: %s\n", tgafooter + 8); 212 213 } else 214 printf("\nTGA footer not found\n"); 215 216 } else 217 printf("\nError: Unable to read TGA footer section\n"); 218 219 } else 220 printf("\nError: Unable to get file size\n"); 221 } 222 223 int 224 main(int argc, char **argv) 225 { 226 printf("\n"); 227 228 if (argc == 2) { 229 BFile file(argv[1], B_READ_ONLY); 230 if (file.InitCheck() != B_OK) 231 printf("Error opening %s\n", argv[1]); 232 else { 233 printf("TGA image information for: %s\n", argv[1]); 234 print_tga_info(file); 235 } 236 } 237 else { 238 printf("tgainfo - reports information about a TGA image file\n"); 239 printf("\nUsage:\n"); 240 printf("tgainfo filename.tga\n"); 241 } 242 243 printf("\n"); 244 245 return 0; 246 } 247 248