130 lines
3.1 KiB
C
130 lines
3.1 KiB
C
#include <stdio.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <limits.h>
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
|
|
#include "joey.h"
|
|
|
|
|
|
#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
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
if (argc < 3) {
|
|
printf("Usage: %s [infile] [outfile] {anyting}\n", argv[0]);
|
|
printf("(If {anything} is provided, image will be displayed as converted until keypress.)\n");
|
|
return 1;
|
|
}
|
|
|
|
jlUtilStartup("STA Converter");
|
|
|
|
int imageFlags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF;
|
|
int imageResult = IMG_Init(imageFlags);
|
|
if ((imageResult & imageFlags) != imageFlags) {
|
|
printf("Failed to initialize SDL2_Image: %s\n", IMG_GetError());
|
|
jlUtilShutdown();
|
|
}
|
|
|
|
SDL_Surface *image = IMG_Load(argv[1]);
|
|
int colors = INT_MAX;
|
|
SDL_Color *c = NULL;
|
|
|
|
if (image->format->palette != NULL) {
|
|
colors = image->format->palette->ncolors;
|
|
if (colors > 16) {
|
|
colors = 16;
|
|
printf("Source palette has more than 16 colors. Only the first 16 will be used.\n");
|
|
}
|
|
c = image->format->palette->colors;
|
|
}
|
|
|
|
printf("%s = %dx%d, %d bits per pixel, %d colors\n", argv[1], image->w, image->h, image->format->BitsPerPixel, colors);
|
|
|
|
if (image->w != 320 || image->h != 200 || image->format->BitsPerPixel != 8 || colors > 16) {
|
|
printf("Image must be 320x200 pixels, 8 bits per pixel, with 16 or fewer colors.\n");
|
|
free(image);
|
|
IMG_Quit();
|
|
jlUtilShutdown();
|
|
}
|
|
|
|
jlStaT *sta = NULL;
|
|
jlStaCreate(sta);
|
|
|
|
for (int x=0; x<colors; x++) {
|
|
sta->palette[x].r = c[x].r / 16;
|
|
sta->palette[x].g = c[x].g / 16;
|
|
sta->palette[x].b = c[x].b / 16;
|
|
printf("Palette %03d = R%03d G%03d B%03d\n", x, sta->palette[x].r, sta->palette[x].g, sta->palette[x].b);
|
|
}
|
|
|
|
if (colors < 16) {
|
|
for (int x=colors; x<16; x++) {
|
|
sta->palette[x].r = 0;
|
|
sta->palette[x].g = 0;
|
|
sta->palette[x].b = 0;
|
|
printf("Palette %03d = R000 G000 B000 (added)\n", x);
|
|
}
|
|
}
|
|
|
|
int p = 0;
|
|
for (int y=0; y<image->h; y++) {
|
|
for (int x=0; x<image->w; x+=2) {
|
|
//printf("%02X %02X ", getPixel(image, x, y), getPixel(image, x + 1, y));
|
|
// These are backwards - no idea why yet.
|
|
sta->pixels[p].r = (unsigned char)getPixel(image, x, y);
|
|
sta->pixels[p++].l = (unsigned char)getPixel(image, x + 1, y);
|
|
}
|
|
}
|
|
|
|
jlStaSave(sta, argv[2]);
|
|
|
|
SDL_FreeSurface(image);
|
|
|
|
if (argc > 3) {
|
|
jlStaDisplay(sta);
|
|
jlDisplayPresent();
|
|
jlKeyWaitForAny();
|
|
}
|
|
|
|
IMG_Quit();
|
|
jlUtilShutdown();
|
|
}
|