A very small library for reading image files
at main 4.4 kB view raw
1#include "img.h" 2#include <stdio.h> 3#include <string.h> 4 5struct Ctx { 6 FILE *file; 7}; 8 9static ImgStatus ctxRead(ImgAny user, ImgAny buf, ImgSz bufSz) 10{ 11 struct Ctx *ctx = user; 12 if(fread(buf, bufSz, 1, ctx->file) != 1) { 13 return ImgErrIO; 14 } 15 return ImgOK; 16} 17 18static ImgStatus ctxSeek(ImgAny user, ImgOff off) 19{ 20 struct Ctx *ctx = user; 21 fseek(ctx->file, off, SEEK_CUR); 22 return ImgOK; 23} 24 25static ImgStatus ctxClose(ImgAny user) 26{ 27 struct Ctx *ctx = user; 28 fclose(ctx->file); 29 return ImgOK; 30} 31 32int main(int argc, char **argv) 33{ 34 if(argc < 2) { 35 printf("Usage: %s <file>\n", argv[0]); 36 return 1; 37 } 38 39 int dumpColorMap = 0; 40 for(int i = 2; i < argc; ++i) { 41 /* BMP Color Table, TGA Color Map */ 42 if(strcmp(argv[i], "-colorMap") == 0 43 || strcmp(argv[i], "-colorTable") == 0) { 44 dumpColorMap = 1; 45 } 46 } 47 48 FILE *file = fopen(argv[1], "rb"); 49 if(file == NULL) { 50 perror("Could not open file"); 51 return 1; 52 } 53 54 struct Ctx ctx; 55 ctx.file = file; 56 ImgFuncs funcs; 57 funcs.user = &ctx; 58 funcs.read = &ctxRead; 59 funcs.seek = &ctxSeek; 60 funcs.close = &ctxClose; 61 62 Img img; 63 ImgStatus status = imgOpen(&img, &funcs); 64 if(status != ImgOK) { 65 printf("Could not open image: %s\n", imgStatusMessage(status)); 66 return 1; 67 } 68 69 printf( 70 "Detected %s\n" 71 "Size: %ux%u\n" 72 "Channel count: %u\n", 73 imgFormatName(img.format), 74 img.width, img.height, 75 img.channelCount); 76 77 switch(img.format) { 78 case ImgFormatQoi: 79 printf("Color space: %s\n", 80 img.qoi.colorSpace == 0 ? "sRGB" : "Linear"); 81 break; 82 case ImgFormatPbm: 83 printf( 84 "Variant: %c\n" 85 "Max. value: %u\n", 86 img.pbm.variant, 87 img.pbm.max); 88 break; 89 case ImgFormatBmp: 90 printf( 91 "Bitmap offset: %08X\n" 92 "Header size: %u\n" 93 "Bit count: %u\n" 94 "Compression: %u\n" 95 "Image size: %u\n" 96 "X pixels per meter: %d\n" 97 "Y pixels per meter: %d\n" 98 "Color table size: %u\n", 99 img.bmp.bitmapOffset, 100 img.bmp.headerSize, 101 img.bmp.bitCount, 102 img.bmp.compression, 103 img.bmp.imageSize, 104 img.bmp.xPPM, 105 img.bmp.yPPM, 106 img.bmp.colorTableSize); 107 if(dumpColorMap && img.bmp.colorTableSize) { 108 printf(" Color table:\n"); 109 for(int i = 0; i < img.bmp.colorTableSize; ++i) { 110 const struct ImgBmpRGBQuad *color = &img.bmp.colorTable[i]; 111 printf(" %u,%u,%u,%u\n", 112 color->red, color->green, color->blue, color->reserved); 113 } 114 } 115 break; 116 case ImgFormatTga: 117 printf( 118 "ID: %s\n" 119 "Color map type: %u\n" 120 "Image type: %u\n" 121 "Color map first index: %u\n" 122 "Color map length: %u\n" 123 "Color map entry size: %u\n" 124 "Origin X: %u\n" 125 "Origin Y: %u\n" 126 "Pixel Depth: %u\n" 127 "Image Origin: %u\n" 128 "Alpha Bits: %u\n", 129 img.tga.id, 130 img.tga.colorMapType, 131 img.tga.imageType, 132 img.tga.colorMapFirstIndex, 133 img.tga.colorMapLength, 134 img.tga.colorMapEntrySize, 135 img.tga.originX, 136 img.tga.originY, 137 img.tga.pixelDepth, 138 img.tga.imageOrigin, 139 img.tga.alphaBits); 140 if(dumpColorMap && img.tga.colorMapType) { 141 printf(" Color map:\n"); 142 for(int i = 0; i < img.tga.colorMapLength; ++i) { 143 const struct ImgTgaColor *color = &img.tga.colorMap[i]; 144 printf(" %u,%u,%u,%u\n", 145 color->red, color->green, color->blue, color->alpha); 146 } 147 } 148 break; 149 case ImgFormatGif: 150 printf( 151 "Global Color Table Flag: %u\n" 152 "Color Resolution: %u\n" 153 "Sort Flag: %u\n" 154 "Global Color Table Size: %u\n" 155 "Background Color Index: %u\n" 156 "Pixel Aspect Ratio: %u\n", 157 img.gif.globalColorTableFlag, 158 img.gif.colorResolution, 159 img.gif.sortFlag, 160 img.gif.globalColorTableSize, 161 img.gif.backgroundColorIndex, 162 img.gif.pixelAspectRatio); 163 if(dumpColorMap && img.gif.globalColorTableFlag) { 164 printf(" Global Color Table:\n"); 165 for(int i = 0; i < img.gif.globalColorTableSize; ++i) { 166 const struct ImgGifColor *color = &img.gif.globalColorTable[i]; 167 printf(" %u,%u,%u\n", 168 color->red, color->green, color->blue); 169 } 170 } 171 break; 172 default: 173 break; 174 } 175 176 status = imgClose(&img); 177 if(status != ImgOK) { 178 printf("Could not close image: %s\n", imgStatusMessage(status)); 179 return 1; 180 } 181 182 return 0; 183}