Blob Blame History Raw

#include <stdio.h>
#include <stdlib.h>

#pragma pack(push,1)
typedef struct {
  unsigned char  idLength;
  unsigned char  colormapType;
  unsigned char  imageType;
  unsigned char  colormapIndex[2];
  unsigned char  colormapLength[2];
  unsigned char  colormapSize;
  unsigned char  xOrigin[2];
  unsigned char  yOrigin[2];
  unsigned char  width[2];
  unsigned char  height[2];
  unsigned char  pixelSize;
  unsigned char  attributes;
} TgaHeader;
#pragma pack(pop)


unsigned short getLEU16(unsigned char *c)
    { return c[0] | ((unsigned short)c[1] << 8); }


int imageLoadTga(const char *path, int *outWidth, int *outHeight, unsigned char **pixels) {
  *outWidth = *outHeight = 0; *pixels = NULL;

  FILE *f = fopen(path, "rb");
    if (!f) {
    fprintf(stderr, "Cannot open for read: %s\n", path);
    fflush(stderr);
    return 0;
  }

  TgaHeader header = {};
  fread(&header, sizeof(header), 1, f); // todo: endianess

  //printf("%d %d %d %d %d\n", header.imageType, header.width, header.height, header.colormapType, header.pixelSize);

  if ( header.imageType != 2
    || (!header.width[0] && !header.width[1])
    || (!header.height[0] && !header.height[1])
    || header.colormapType
    || (header.pixelSize != 24 && header.pixelSize != 32)
  ) {
    fprintf(stderr, "Unsupported format. Only uncompressed 24 or 32 bits TGA are supported: %s\n", path);
    fflush(stderr);
    return 0;
  }

  fseek(f, header.idLength, SEEK_CUR);

  int w = *outWidth = getLEU16(header.width);
  int h = *outHeight = getLEU16(header.height);
  int rowSize = w*4;
  int size = h*rowSize;
  *pixels = (unsigned char*)calloc(1, size);
  unsigned char *row = *pixels + size;
  for(unsigned short r = h; r; --r, row -= rowSize) {
    for(unsigned char *c = row - rowSize; c < row; c += 4) {
      c[2] = fgetc(f);
      c[1] = fgetc(f);
      c[0] = fgetc(f);
      c[3] = header.pixelSize == 32 ? fgetc(f) : 255;
    }
  }
  fclose(f);

  return 1;
}


int main(int argc, char **argv) {
    // for(int i = 32; i < 127; ++i) fputc(i, stdout); fputc('\n', stdout);

    const char table1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const char table2[] = " !#$%&'()*,-.:;<=>?@[]^_`{|}~";
    int max1 = sizeof(table1)-1;
    int max2 = sizeof(table2)-1;

    int w, h;
    unsigned char *p;
    if (argc <= 1) return 1;
    if (!imageLoadTga(argv[1], &w, &h, &p)) return 1;

    int cnt = 0, bit = 0, line = 0;
    unsigned char *e = p + w*h*4;
    fputs("    \"", stdout);
    while(1) {
        if (p >= e || (*p > 127) != bit) {
            char str[128], *c = str + sizeof(str); *--c = 0;
            *--c = table1[cnt%max1], cnt /= max1;
            while(cnt) *--c = table2[cnt%max2], cnt /= max2;
            while(*c) {
                fputc(*c++, stdout);
                if (++line == 200) fputs("\"\n    \"", stdout), line = 0;
            }
            bit = !bit;
            cnt = 1;
            if (p >= e) break;
        } else ++cnt;
        p += 4;
    }
    fputs("\";\n", stdout);

    return 0;
}