2019-02-25 17:28:42 +00:00
|
|
|
/*****************************************/
|
|
|
|
/* Converts a PNG to LZ4 compressed data */
|
|
|
|
/*****************************************/
|
|
|
|
/* Note, it ignores memory holes so only */
|
|
|
|
/* safe to load high and copy to the right location */
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
2019-02-26 02:01:06 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
2019-02-25 17:28:42 +00:00
|
|
|
#include "loadpng.h"
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
#include "lz4.h"
|
|
|
|
#include "lz4hc.h"
|
|
|
|
|
|
|
|
|
2019-02-25 17:28:42 +00:00
|
|
|
#define OUTPUT_C 0
|
|
|
|
#define OUTPUT_ASM 1
|
|
|
|
#define OUTPUT_RAW 2
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
static int gr_offsets[24]={
|
|
|
|
0x400,0x480,0x500,0x580,0x600,0x680,0x700,0x780,
|
|
|
|
0x428,0x4A8,0x528,0x5A8,0x628,0x6A8,0x728,0x7A8,
|
|
|
|
0x450,0x4D0,0x550,0x5D0,0x650,0x6D0,0x750,0x7D0,
|
|
|
|
};
|
2019-02-25 17:28:42 +00:00
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
static int gr_lz4(int out_type, char *varname, int xsize, int ysize,
|
2019-02-25 17:28:42 +00:00
|
|
|
unsigned char *image) {
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
unsigned char gr[1024];
|
|
|
|
unsigned char output[2048];
|
|
|
|
int x,y;
|
2019-02-26 02:01:06 +00:00
|
|
|
int size,count=0;
|
2019-02-25 17:53:51 +00:00
|
|
|
|
2019-02-25 17:28:42 +00:00
|
|
|
/* our image pointer is not-interleaved, but it does */
|
|
|
|
/* have the top/bottom pixels properly packed for us */
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
memset(gr,0,1024);
|
|
|
|
|
|
|
|
if ((xsize!=40) && (ysize!=48)) {
|
|
|
|
fprintf(stderr,"Error, wrong file size\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy our image into raw interleaved GR format */
|
|
|
|
for(y=0;y<24;y++) {
|
|
|
|
for(x=0;x<40;x++) {
|
|
|
|
gr[(gr_offsets[y]-0x400)+x]=
|
2019-02-26 02:01:06 +00:00
|
|
|
image[(y*xsize)+x];
|
2019-02-25 17:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill in holes */
|
|
|
|
/* Fill with last color in line for extra compression? */
|
|
|
|
for(x=0x478;x<0x480;x++) gr[x-0x400]=gr[0x477-0x400];
|
|
|
|
for(x=0x578;x<0x580;x++) gr[x-0x400]=gr[0x577-0x400];
|
|
|
|
for(x=0x678;x<0x680;x++) gr[x-0x400]=gr[0x677-0x400];
|
|
|
|
for(x=0x778;x<0x780;x++) gr[x-0x400]=gr[0x777-0x400];
|
|
|
|
|
|
|
|
/* Now lz4 compress the thing */
|
|
|
|
|
|
|
|
size=LZ4_compress_HC ((char *)gr,// src
|
|
|
|
(char *)output, // dest
|
|
|
|
1024, // src size
|
|
|
|
2048, // src capacity
|
|
|
|
16); // compression level
|
|
|
|
|
2019-02-26 02:01:06 +00:00
|
|
|
|
|
|
|
/* Note, unlike the on-disk format we do *not* */
|
|
|
|
/* have to skip 11 bytes at front or 8 bytes at end */
|
|
|
|
/* also, we write the 16-bit size (little endian) at front */
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
if (out_type==OUTPUT_C) {
|
|
|
|
fprintf(stdout,"unsigned char %s[]={",varname);
|
2019-02-26 02:01:06 +00:00
|
|
|
printf("\t0x%02X,0x%02X,\n",(size)&0xff,
|
|
|
|
((size)>>8)&0xff);
|
2019-02-25 17:53:51 +00:00
|
|
|
for(x=0;x<size;x++) {
|
2019-02-26 02:01:06 +00:00
|
|
|
if (count%16==0) {
|
2019-02-25 17:53:51 +00:00
|
|
|
printf("\n\t");
|
|
|
|
}
|
|
|
|
printf("0x%02X,",output[x]);
|
2019-02-26 02:01:06 +00:00
|
|
|
count++;
|
2019-02-25 17:53:51 +00:00
|
|
|
}
|
|
|
|
printf("\n};\n");
|
|
|
|
}
|
|
|
|
else if (out_type==OUTPUT_ASM) {
|
2019-02-26 02:01:06 +00:00
|
|
|
// int blargh;
|
|
|
|
// blargh=open("blargh",O_CREAT|O_WRONLY,0777);
|
|
|
|
// write(blargh,gr,1024);
|
|
|
|
// close(blargh);
|
|
|
|
|
|
|
|
fprintf(stdout,"%s:\n",varname);
|
|
|
|
|
|
|
|
// size includes this size value
|
|
|
|
printf("\t.byte $%02X,$%02X",(size+2)&0xff,
|
|
|
|
((size+2)>>8)&0xff);
|
2019-02-25 17:53:51 +00:00
|
|
|
for(x=0;x<size;x++) {
|
2019-02-26 02:01:06 +00:00
|
|
|
if (count%16==0) {
|
2019-02-25 17:53:51 +00:00
|
|
|
printf("\n\t.byte ");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf(",");
|
|
|
|
}
|
|
|
|
printf("$%02X",output[x]);
|
2019-02-26 02:01:06 +00:00
|
|
|
count++;
|
2019-02-25 17:53:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (out_type==OUTPUT_RAW) {
|
|
|
|
write(1,output,size);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-02-26 02:01:06 +00:00
|
|
|
return (size+2);
|
2019-02-25 17:28:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Converts a PNG to LZ4 compressed data */
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
unsigned char *image;
|
|
|
|
int xsize,ysize;
|
|
|
|
int size=0;
|
|
|
|
int out_type=OUTPUT_C;
|
|
|
|
|
|
|
|
if (argc<4) {
|
|
|
|
fprintf(stderr,"Usage:\t%s type INFILE varname\n\n",argv[0]);
|
|
|
|
fprintf(stderr,"\ttype: c or asm or raw\n");
|
|
|
|
fprintf(stderr,"\tvarname: label for graphic\n");
|
|
|
|
fprintf(stderr,"\n");
|
|
|
|
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(argv[1],"c")) {
|
|
|
|
out_type=OUTPUT_C;
|
|
|
|
}
|
|
|
|
else if (!strcmp(argv[1],"asm")) {
|
|
|
|
out_type=OUTPUT_ASM;
|
|
|
|
}
|
|
|
|
else if (!strcmp(argv[1],"raw")) {
|
|
|
|
out_type=OUTPUT_RAW;
|
|
|
|
}
|
|
|
|
|
2019-09-04 19:49:53 +00:00
|
|
|
if (loadpng(argv[2],&image,&xsize,&ysize,PNG_WHOLETHING)<0) {
|
2019-02-25 17:28:42 +00:00
|
|
|
fprintf(stderr,"Error loading png!\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
2019-03-02 03:01:46 +00:00
|
|
|
printf("\n");
|
|
|
|
|
2019-02-25 17:28:42 +00:00
|
|
|
fprintf(stderr,"Loaded image %d by %d\n",xsize,ysize);
|
|
|
|
|
|
|
|
size=gr_lz4(out_type,argv[3],
|
|
|
|
xsize,ysize,image);
|
|
|
|
|
2019-02-25 17:53:51 +00:00
|
|
|
if (size<0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-02-25 17:28:42 +00:00
|
|
|
fprintf(stderr,"Size %d bytes\n",size);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|