hgr2png: this is harder than it looks

This commit is contained in:
Vince Weaver 2021-01-23 15:44:46 -05:00
parent f45a30dec7
commit e66a20a074
3 changed files with 451 additions and 3 deletions

View File

@ -3,6 +3,13 @@ include ../../../Makefile.inc
PNG2RLE = ../../../utils/gr-utils/png2rle
PNG2GR = ../../../utils/gr-utils/png2gr
LZSA = ~/research/lzsa/lzsa/lzsa
B2D = ../../../utils/bmp2dhr/b2d
all: tfv_title.inc planets_warwick.hgr
planets_warwick_hgr: planets_warwick.bmp
$(B2D)
tfv_title.inc: \
title.lzsa

View File

@ -2,7 +2,7 @@ include ../../Makefile.inc
CFLAGS = -O2 -Wall -g
all: pcx2hgr png2hgr png2dhgr shape_table dump_table
all: pcx2hgr png2hgr png2dhgr shape_table dump_table hgr2png
dump_table: dump_table.o
$(CC) -o dump_table dump_table.o $(LFLAGS)
@ -22,6 +22,7 @@ pcx2hgr: pcx2hgr.o
pcx2hgr.o: pcx2hgr.c
$(CC) $(CFLAGS) -c pcx2hgr.c
###
png2hgr: png2hgr.o
$(CC) -o png2hgr png2hgr.o $(LFLAGS) -lpng
@ -29,6 +30,16 @@ png2hgr: png2hgr.o
png2hgr.o: png2hgr.c
$(CC) $(CFLAGS) -c png2hgr.c
###
hgr2png: hgr2png.o
$(CC) -o hgr2png hgr2png.o $(LFLAGS) -lpng
hgr2png.o: hgr2png.c
$(CC) $(CFLAGS) -c hgr2png.c
###
png2dhgr: png2dhgr.o
$(CC) -o png2dhgr png2dhgr.o $(LFLAGS) -lpng
@ -38,8 +49,8 @@ png2dhgr.o: png2dhgr.c
install:
cp pcx2hgr shape_table png2hgr $(INSTALL_LOC)
cp pcx2hgr shape_table png2hgr hgr2png $(INSTALL_LOC)
clean:
rm -f *~ *.o pcx2hgr shape_table dump_table png2hgr png2dhgr
rm -f *~ *.o pcx2hgr shape_table dump_table png2hgr png2dhgr hgr2png

430
utils/hgr-utils/hgr2png.c Normal file
View File

@ -0,0 +1,430 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <png.h>
#define PAL_LENGTH 8 // PNG_MAX_PALETTE_LENGTH
static int hgr_offset_table[48]={
0x0000,0x0080,0x0100,0x0180,0x0200,0x0280,0x0300,0x0380,
0x0028,0x00A8,0x0128,0x01A8,0x0228,0x02A8,0x0328,0x03A8,
0x0050,0x00D0,0x0150,0x01D0,0x0250,0x02D0,0x0350,0x03D0,
};
static int hgr_offset(int y) {
int temp,temp2,address;
temp=y/8;
temp2=y%8;
temp2=temp2*0x400;
address=hgr_offset_table[temp]+temp2;
return address;
}
#define COLOR_BLACK0 0
#define COLOR_GREEN 1
#define COLOR_PURPLE 2
#define COLOR_WHITE0 3
#define COLOR_BLACK1 4
#define COLOR_ORANGE 5
#define COLOR_BLUE 6
#define COLOR_WHITE1 7
/* 000 00 00 -> black black black black */
/* 000 00 01 -> purpl black black black */
/* 000 00 10 -> black green black black */
/* 000 00 11 -> white white black black */
/* 000 01 00 -> black black purpl black */
/* 000 01 01 -> purpl purpl purpl black !!! */
/* 000 01 10 -> black white white black !!! */
/* 000 01 11 -> white white white black */
/* 000 10 00 -> black black black green */
/* 000 10 01 -> purpl black black green */
/* 000 10 10 -> black green green black */
/* 000 10 11 -> white white green green */
/* 000 11 00 -> black black white white */
/* 000 11 01 -> purpl purpl white white !!! */
/* 000 11 10 -> black white white white !!! */
/* 000 11 11 -> white white white white */
/* even odd */
/* 000 00 00 -> black black black black */
/* 000 00 01 -> purpl black black black */
/* 000 00 10 -> black green black black */
/* 000 00 11 -> white white black black */
/* 000 01 00 -> black black purpl black */
/* 000 01 01 -> purpl purpl purpl black !!! */
/* 000 01 10 -> black white white black !!! */
/* 000 01 11 -> white white white black */
// even = purple blue
// odd = green orange
static int hgr_color_even(int high, int first, int second, int next) {
if (!high) {
if ((second==0) && (first==0)) return COLOR_BLACK0;
if ((second==0) && (first==1)) {
if (next==0) return COLOR_PURPLE;
else return COLOR_PURPLE;
}
if ((second==1) && (first==0)) {
if (next==0) return COLOR_BLACK0;
else return COLOR_BLACK0;
}
if ((second==1) && (first==1)) return COLOR_WHITE0;
}
else {
if ((second==0) && (first==0)) return COLOR_BLACK1;
if ((second==0) && (first==1)) {
if (next==0) return COLOR_BLUE;
else return COLOR_BLUE;
}
if ((second==1) && (first==0)) {
if (next==0) return COLOR_BLACK1;
else return COLOR_BLACK1;
}
if ((second==1) && (first==1)) return COLOR_WHITE1;
}
return 0;
}
/* even odd */
/* 000 00 00 -> black black black black */
/* 000 00 01 -> purpl black black black */
/* 000 00 10 -> black green black black */
/* 000 00 11 -> white white black black */
/* 000 01 00 -> black black purpl black */
/* 000 01 01 -> purpl purpl purpl black !!! */
/* 000 01 10 -> black white white black !!! */
/* 000 01 11 -> white white white black */
static int hgr_color_odd(int high, int first, int second,int next) {
if (!high) {
if ((second==0) && (first==0)) return COLOR_BLACK0;
if ((second==0) && (first==1)) {
if (next==0) return COLOR_BLACK0;
else return COLOR_PURPLE;
}
if ((second==1) && (first==0)) {
if (next==0) return COLOR_GREEN;
else return COLOR_WHITE0;
}
if ((second==1) && (first==1)) return COLOR_WHITE0;
}
else {
if ((second==0) && (first==0)) return COLOR_BLACK1;
if ((second==0) && (first==1)) {
if (next==0) return COLOR_BLACK1;
else return COLOR_BLUE;
}
if ((second==1) && (first==0)) {
if (next==0) return COLOR_ORANGE;
else return COLOR_WHITE1;
}
if ((second==1) && (first==1)) return COLOR_WHITE1;
}
return 0;
}
int main(int argc, char **argv) {
int fd;
char filename[256];
char screen[8192];
FILE *output;
int width=280,height=192,y,x;
png_byte color_type=PNG_COLOR_TYPE_PALETTE;
png_byte bit_depth=8;
png_structp png_ptr;
png_infop info_ptr;
// int number_of_passes;
png_bytep *row_pointers;
png_colorp palette;
png_color *col;
if (argc<2) {
fprintf(stderr,"Usage: hgr2 FILENAME OUTPUT\n");
fprintf(stderr," where FILENAME is an 8k AppleII HIRES image\n\n");
return -1;
}
if (argc<3) {
sprintf(filename,"%s.png",argv[1]);
}
else {
strncpy(filename,argv[2],256-1);
}
fd=open(argv[1],O_RDONLY);
if (fd<0) {
printf("Error opening %s! %s\n",argv[1],strerror(errno));
return -1;
}
read(fd,screen,8192);
close(fd);
output = fopen(filename, "wb");
if (output==NULL) {
printf("Error opening %s, %s\n",filename,strerror(errno));
return -1;
}
/* initialize */
png_ptr = png_create_write_struct(
PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr==NULL) {
fprintf(stderr,"Error! png_create_write_struct() failed\n");
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr==NULL) {
fprintf(stderr,"Error! png_create_info_struct() failed\n");
return -1;
}
// setjmp(png_jmpbuf(png_ptr));
png_init_io(png_ptr, output);
/* write header */
// setjmp(png_jmpbuf(png_ptr));
png_set_IHDR(png_ptr, info_ptr, width, height,
bit_depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
// png_write_info(png_ptr, info_ptr);
/* set palette */
palette = (png_colorp)png_malloc(png_ptr,
PAL_LENGTH * (sizeof (png_color)));
/* 0: black 0 */
col=&palette[0];
col->red=0;
col->green=0;
col->blue=0;
/* 1: green */
col=&palette[1];
col->red=0x1b;
col->green=0xcb;
col->blue=0x01;
/* 2: purple */
col=&palette[2];
col->red=0xe4;
col->green=0x34;
col->blue=0xfe;
/* 3: white0 */
col=&palette[3];
col->red=0xff;
col->green=0xff;
col->blue=0xff;
/* 4: black1 */
col=&palette[4];
col->red=0;
col->green=0;
col->blue=0;
/* 5: orange */
col=&palette[5];
col->red=0xcd;
col->green=0x5b;
col->blue=0x01;
/* 6: blue */
col=&palette[6];
col->red=0x1b;
col->green=0x9a;
col->blue=0xfe;
/* 7: white1 */
col=&palette[7];
col->red=0xff;
col->green=0xff;
col->blue=0xff;
/* ... Set palette colors ... */
png_set_PLTE(png_ptr, info_ptr, palette, PAL_LENGTH);
png_write_info(png_ptr, info_ptr);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for(y=0;y<height;y++) {
row_pointers[y]=malloc(width);
}
/*********************************************/
/* do the actual conversion */
/*********************************************/
unsigned char byte1,byte2,byte3;
int out_ptr,color1,color2;
for(y=0;y<height;y++) {
out_ptr=0;
for(x=0;x<20;x++) {
byte1=screen[hgr_offset(y)+x*2];
byte2=screen[hgr_offset(y)+x*2+1];
if (x==19) byte3=0;
else byte3=screen[hgr_offset(y)+x*2+2];
/* 10 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte1&0x80,
(byte1>>0)&0x1,
(byte1>>1)&0x1,
(byte1>>2)&0x1);
color2=hgr_color_odd(byte1&0x80,
(byte1>>0)&0x1,
(byte1>>1)&0x1,
(byte1>>2)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 32 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte1&0x80,
(byte1>>2)&0x1,
(byte1>>3)&0x1,
(byte1>>4)&0x1);
color2=hgr_color_odd(byte1&0x80,
(byte1>>2)&0x1,
(byte1>>3)&0x1,
(byte1>>4)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 54 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte1&0x80,
(byte1>>4)&0x1,
(byte1>>5)&0x1,
(byte1>>6)&0x1);
color2=hgr_color_odd(byte1&0x80,
(byte1>>4)&0x1,
(byte1>>5)&0x1,
(byte1>>6)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 06 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte1&0x80,
(byte1>>6)&0x1,
(byte2>>0)&0x1,
(byte2>>1)&0x1);
color2=hgr_color_odd(byte2&0x80,
(byte1>>6)&0x1,
(byte2>>0)&0x1,
(byte2>>1)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 21 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte2&0x80,
(byte2>>1)&0x1,
(byte2>>2)&0x1,
(byte2>>3)&0x1);
color2=hgr_color_odd(byte2&0x80,
(byte2>>1)&0x1,
(byte2>>2)&0x1,
(byte2>>3)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 43 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte2&0x80,
(byte2>>3)&0x1,
(byte2>>4)&0x1,
(byte2>>5)&0x1);
color2=hgr_color_odd(byte2&0x80,
(byte2>>3)&0x1,
(byte2>>4)&0x1,
(byte2>>5)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
/* 65 */
/* high bit, left_bit, middle_bit, right_bit */
color1=hgr_color_even(byte2&0x80,
(byte2>>5)&0x1,
(byte2>>6)&0x1,
(byte3>>0)&0x1);
color2=hgr_color_odd(byte2&0x80,
(byte2>>5)&0x1,
(byte2>>6)&0x1,
(byte3>>0)&0x1);
row_pointers[y][out_ptr]=color1;
out_ptr++;
row_pointers[y][out_ptr]=color2;
out_ptr++;
}
}
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, NULL);
/* cleanup heap allocation */
for (y=0; y<height; y++) {
free(row_pointers[y]);
}
free(row_pointers);
fclose(output);
return 0;
}