aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Murphy <alec@checksum.fail>2017-07-08 02:35:52 -0400
committerAlec Murphy <alec@checksum.fail>2017-07-08 02:35:52 -0400
commit9eabaeab79df776c35b8833e3bb64719c1136052 (patch)
treeed57ca083c8e40aa5ce96f1a4973b32a120e3352
parentc9303b0764d596486f173aeb0e70dd79389b6cee (diff)
Initial commit
-rw-r--r--FilePNG.HC247
-rw-r--r--README.md2
-rw-r--r--example.pngbin0 -> 307781 bytes
3 files changed, 249 insertions, 0 deletions
diff --git a/FilePNG.HC b/FilePNG.HC
new file mode 100644
index 0000000..b8ca3ed
--- /dev/null
+++ b/FilePNG.HC
@@ -0,0 +1,247 @@
+#help_index "Graphics/PNG Files"
+
+#define PNG_COLORS_NUM 16
+#define ZLIB_CHUNK_SIZE 65535
+
+class CFilePNG
+{
+ U32 signature[2];
+ U32 ihdr_len;
+ U32 ihdr_typ;
+ U32 width;
+ U32 height;
+ U8 depth;
+ U8 color_type;
+ U8 compress;
+ U8 filter;
+ U8 interlace;
+ U32 ihdr_crc;
+ U32 plte_len;
+ U32 plte_typ;
+ U8 plte_tbl[48];
+ U32 plte_crc;
+ U32 idat_len;
+ U32 idat_typ;
+ U0 data;
+};
+
+U0 AdlerByte32(U8 _byte, U32 _a, U32 _b, U32 *_ra, U32 *_rb)
+{
+ I64 MOD_ADLER=65521;
+ U32 _ta,_tb;
+ _ta = (_a + _byte) % MOD_ADLER;
+ _tb = (_b + _a) % MOD_ADLER;
+ MemCpy(_ra, &_ta, 4);
+ MemCpy(_rb, &_tb, 4);
+}
+
+U32 Crc32(I64 buf, I64 ofs, I64 len)
+{
+ U32 c;
+ U32 crc = 0xFFFFFFFF;
+ U32 crc_table[256];
+ U8 *stream=buf+(ofs-buf);
+ I64 i,k,n;
+ n=0;
+ while (n<256)
+ {
+ c=n;
+ k=0;
+ while (k<8)
+ {
+ if (c&1)
+ {
+ c = (c >> 1) ^ 0xEDB88320;
+ }
+ else
+ {
+ c = (c >> 1) ^ 0;
+ };
+ k++;
+ };
+ crc_table[n] = c;
+ n++;
+ };
+ i=0;
+ while (i<len)
+ {
+ crc = crc_table[(crc ^ stream[i]) & 0xFF] ^ (crc >> 8);
+ //"%02X ",stream[i];
+ i++;
+ }
+ return (crc^0xFFFFFFFF);
+}
+
+public I64 PNGWrite(U8 *filename,CDC *dc,I64 bits=4)
+{//.
+ I64 size=sizeof(CFilePNG)+((dc->width+1)*dc->height);
+ bits=4;
+ CFilePNG *png=CAlloc((dc->width*dc->height)*4);
+ png->signature[0]=htonl(0x89504E47);
+ png->signature[1]=htonl(0x0D0A1A0A);
+ png->ihdr_len=htonl(13);
+ png->ihdr_typ='IHDR';
+ png->width=htonl(dc->width);
+ png->height=htonl(dc->height);
+ png->depth=8;
+ png->color_type=3;
+ png->compress=0;
+ png->filter=0;
+ png->interlace=0;
+ png->ihdr_crc=htonl(Crc32(png,&png->ihdr_typ,ntohl(png->ihdr_len)+4));
+ png->plte_len=htonl(48);
+ png->plte_typ='PLTE';
+
+ // use the default palette for now
+ png->plte_tbl[00]=0x00;
+ png->plte_tbl[01]=0x00;
+ png->plte_tbl[02]=0x00;
+
+ png->plte_tbl[03]=0x00;
+ png->plte_tbl[04]=0x00;
+ png->plte_tbl[05]=0xAA;
+
+ png->plte_tbl[06]=0x00;
+ png->plte_tbl[07]=0xAA;
+ png->plte_tbl[08]=0x00;
+
+ png->plte_tbl[09]=0x00;
+ png->plte_tbl[10]=0xAA;
+ png->plte_tbl[11]=0xAA;
+
+ png->plte_tbl[12]=0xAA;
+ png->plte_tbl[13]=0x00;
+ png->plte_tbl[14]=0x00;
+
+ png->plte_tbl[15]=0xAA;
+ png->plte_tbl[16]=0x00;
+ png->plte_tbl[17]=0xAA;
+
+ png->plte_tbl[18]=0xAA;
+ png->plte_tbl[19]=0x55;
+ png->plte_tbl[20]=0x00;
+
+ png->plte_tbl[21]=0xAA;
+ png->plte_tbl[22]=0xAA;
+ png->plte_tbl[23]=0xAA;
+
+ png->plte_tbl[24]=0x55;
+ png->plte_tbl[25]=0x55;
+ png->plte_tbl[26]=0x55;
+
+ png->plte_tbl[27]=0x55;
+ png->plte_tbl[28]=0x55;
+ png->plte_tbl[29]=0xFF;
+
+ png->plte_tbl[30]=0x55;
+ png->plte_tbl[31]=0xFF;
+ png->plte_tbl[32]=0x55;
+
+ png->plte_tbl[33]=0x55;
+ png->plte_tbl[34]=0xFF;
+ png->plte_tbl[35]=0xFF;
+
+ png->plte_tbl[36]=0xFF;
+ png->plte_tbl[37]=0x55;
+ png->plte_tbl[38]=0x55;
+
+ png->plte_tbl[39]=0xFF;
+ png->plte_tbl[40]=0x55;
+ png->plte_tbl[41]=0xFF;
+
+ png->plte_tbl[42]=0xFF;
+ png->plte_tbl[43]=0xFF;
+ png->plte_tbl[44]=0x55;
+
+ png->plte_tbl[45]=0xFF;
+ png->plte_tbl[46]=0xFF;
+ png->plte_tbl[47]=0xFF;
+
+ png->plte_crc=htonl(Crc32(png,&png->plte_typ,ntohl(png->plte_len)+4));
+
+ I64 id_clen=0;
+
+ png->idat_typ='IDAT';
+ U8 *data=&png->data;
+ I64 d_ctr=2;
+
+ // zlib header
+ data[0]=0x78;
+ data[1]=0x01;
+
+ I64 z_maxchk=(((dc->width+1)*dc->height))/ZLIB_CHUNK_SIZE;
+ I64 z_curchk=0;
+ I64 chk_pos;
+ I64 chk_size;
+ I64 px_pos=0;
+ I64 scan;
+ U32 *chk_a32;
+ U32 _a, _b;
+
+ scan=-1;
+
+ while (z_curchk<z_maxchk+1)
+ {
+ chk_size=ZLIB_CHUNK_SIZE;
+ data[d_ctr+0]=0x0;
+ if(z_curchk==(z_maxchk))
+ {
+ // last chunk.
+ data[d_ctr+0]=0x1;
+ chk_size=(((dc->width+1)*dc->height))%ZLIB_CHUNK_SIZE;
+ };
+
+ // chunk size
+ data[d_ctr+1]=chk_size & 0xFF;
+ data[d_ctr+2]=chk_size >> 8;
+ data[d_ctr+3]=(ZLIB_CHUNK_SIZE-chk_size) & 0xFF;
+ data[d_ctr+4]=(ZLIB_CHUNK_SIZE-chk_size) >> 8;
+
+ chk_pos=0;
+ while(chk_pos<(chk_size))
+ {
+ if (scan==-1)
+ {
+ data[d_ctr+5+chk_pos]=0;
+ }
+ else
+ {
+ data[d_ctr+5+chk_pos]=dc->body[px_pos];
+ px_pos++;
+ };
+ AdlerByte32(data[d_ctr+5+chk_pos], _a, _b, &_a, &_b);
+ chk_pos++;
+ scan++;
+ if(scan==dc->width)
+ {
+ scan=-1;
+ };
+ };
+
+ z_curchk++;
+ d_ctr += 5+chk_pos;
+ };
+
+ chk_a32=(data+d_ctr);
+ chk_a32[0]=htonl((_b << 16) | _a);
+
+ id_clen = d_ctr+4;
+ png->idat_len=htonl(id_clen);
+ chk_a32[1]=htonl(Crc32(png,&png->idat_typ,ntohl(png->idat_len)+4));
+ chk_a32[2]=0;
+ chk_a32[3]='IEND';
+ chk_a32[4]=htonl(0xAE426082);
+ FileWrite(filename,png,size);
+ Free(png);
+ return size;
+}
+
+#help_index "Graphics/PNG Files;Graphics/Scrn"
+public I64 PNGScrnCapture(U8 *filename,I64 bits=4,Bool include_zoom=TRUE)
+{//Capture scrn as PNG file.
+ I64 size=0;
+ CDC *dc=DCScrnCapture(include_zoom);
+ size=PNGWrite(filename,dc,bits);
+ DCDel(dc);
+ return size;
+}
diff --git a/README.md b/README.md
index 4f99570..9757828 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
# filepng
PNG support for TempleOS
+
+![FilePNG](https://raw.githubusercontent.com/tramplersheikhs/filepng/master/example.png "FilePNG")
diff --git a/example.png b/example.png
new file mode 100644
index 0000000..ea91b0e
--- /dev/null
+++ b/example.png
Binary files differ