#include #include #include #include #include #include #include "joey.h" void convertColor(char *filename, char *basename, bool showIt); void convertStencil(char *filename, char *basename); bool fileExists(char *filename); Uint32 getPixel(SDL_Surface *surface, int x, int y); SDL_Surface *loadImage(char *filename); void convertColor(char *filename, char *basename, bool showIt) { int colors = INT_MAX; SDL_Color *c = NULL; SDL_Surface *image = loadImage(filename); if (image == NULL) return; colors = image->format->palette->ncolors; c = image->format->palette->colors; jlImgT *img = NULL; jlImgCreate(img); for (int x=0; xpalette[x].r = c[x].r / 16; img->palette[x].g = c[x].g / 16; img->palette[x].b = c[x].b / 16; //printf("Palette %03d = R%03d G%03d B%03d\n", x, img->palette[x].r, img->palette[x].g, img->palette[x].b); } if (colors < 16) { for (int x=colors; x<16; x++) { img->palette[x].r = 0; img->palette[x].g = 0; img->palette[x].b = 0; //printf("Palette %03d = R000 G000 B000 (added)\n", x); } } int p = 0; for (int y=0; yh; y++) { for (int x=0; xw; x+=2) { //printf("%02X %02X ", getPixel(image, x, y), getPixel(image, x + 1, y)); // These are backwards - no idea why yet. img->pixels[p].r = (unsigned char)getPixel(image, x, y); img->pixels[p++].l = (unsigned char)getPixel(image, x + 1, y); } } jlImgSave(img, basename); SDL_FreeSurface(image); if (showIt) { jlImgDisplay(img); jlDisplayPresent(); jlKeyWaitForAny(); } jlImgFree(img); } void convertStencil(char *filename, char *basename) { // Stencil files aren't required if (!fileExists(filename)) return; int bytes = 0; byte data = 0; int bits = 0; SDL_Surface *image = loadImage(filename); char name[2048]; FILE *out; snprintf(name, 2048, "%s.stn", basename); out = fopen(name, "wb"); if (!out) { fprintf(stderr, "Unable to save stencil: %s\n", name); return; } fputc('S', out); fputc('T', out); fputc('N', out); fputc( 0, out); for (int y=0; yh; y++) { for (int x=0; xw; x++) { data <<= 1; data |= (getPixel(image, x, y) == 0); bits++; if (bits > 7) { bytes++; bits = 0; fputc(data, out); } } } fclose(out); } bool fileExists(char *filename) { FILE *file; if ((file = fopen(filename, "r+"))) { fclose(file); return true; } return false; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" Uint32 getPixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; switch(bpp) { case 1: return *p; break; case 2: // Generates cast increases required alignment of target type [-Wcast-align] warning. Harmless on x86. return *(Uint16 *)p; break; case 3: if (SDL_BYTEORDER == SDL_BIG_ENDIAN) return (Uint32)(p[0] << 16 | p[1] << 8 | p[2]); else return (Uint32)(p[0] | p[1] << 8 | p[2] << 16); break; case 4: // Generates cast increases required alignment of target type [-Wcast-align] warning. Harmless on x86. return *(Uint32 *)p; break; default: return 0; } } #pragma GCC diagnostic pop SDL_Surface *loadImage(char *filename) { if (!fileExists(filename)) { fprintf(stderr, "Unable to load image: %s\n", filename); return NULL; } SDL_Surface *image = IMG_Load(filename); int colors = INT_MAX; if (image->format->palette != NULL) { colors = image->format->palette->ncolors; } //printf("%s = %dx%d, %d bits per pixel, %d colors\n", filename, image->w, image->h, image->format->BitsPerPixel, colors); if (image->w != 320 || image->h != 200 || colors > 16) { fprintf(stderr, "Image must be 320x200 pixels, 8 bits per pixel, with 16 or fewer colors.\n"); free(image); image = NULL; } return image; } int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: %s [color.png] [stencil.png] [outfile] {anyting}\n", argv[0]); printf("(If {anything} is provided, image will be displayed as converted until keypress.)\n"); return 1; } jlUtilStartup("IMG/STN Converter"); int imageFlags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF; int imageResult = IMG_Init(imageFlags); if ((imageResult & imageFlags) != imageFlags) { fprintf(stderr, "Failed to initialize SDL2_Image: %s\n", IMG_GetError()); jlUtilShutdown(); } convertColor(argv[1], argv[3], argc > 4); convertStencil(argv[2], argv[3]); IMG_Quit(); jlUtilShutdown(); }