#pragma lint -1 #pragma noroot #pragma optimize -1 #include #include #include #include #include "crc.h" #include "png.h" extern int write(int, void *, long); extern pascal long Swap32(long); extern pascal int Swap16(int); //static char PNGHeader[8] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n' }; int writeIEND(Word fd) { IEND iend; iend.chunk.length = 0; iend.chunk.type[0] = 'I'; iend.chunk.type[1] = 'E'; iend.chunk.type[2] = 'N'; iend.chunk.type[3] = 'D'; iend.crc = Swap32(PngCrc(-1, "IEND", 4) ^ 0xffffffff); return (Word)write(fd, &iend, sizeof(IEND)); } int writeIHDR(Word fd, Word height, Word width) { struct IHDR ihdr; ihdr.chunk.length = Swap32(sizeof(IHDR) - sizeof(ChunkHeader) - 4); ihdr.chunk.type[0] = 'I'; ihdr.chunk.type[1] = 'H'; ihdr.chunk.type[2] = 'D'; ihdr.chunk.type[3] = 'R'; ihdr.width = Swap32(width); ihdr.height = Swap32(height); ihdr.bitDepth = 8; ihdr.colorType = 3; // color, pallette. ihdr.compressMethod = 0; ihdr.filterMethod = 0; ihdr.interlaceMethod = 0; // no interlace ihdr.crc = Swap32( PngCrc(-1, (char *)(&ihdr) + 4, sizeof(IHDR) - 8) ^ 0xffffffff); write(fd, PNGHEADER, PNGHEADERSIZE); return (Word)write(fd, &ihdr, sizeof(IHDR)); } int writeTEXT(int fd, const char *key, const char *value) { int klen; int vlen; ChunkHeader header; LongWord crc; if (!key || !*key) return 0; if (!value || !*value) return 0; // key includes trailing NULL. value does not. klen = strlen(key) + 1; vlen = strlen(value); header.length = klen + vlen; header.type[0] = 't'; header.type[1] = 'E'; header.type[2] = 'X'; header.type[3] = 't'; write(fd, &header, sizeof(header)); write(fd, key, klen); write(fd, value, vlen); crc = PngCrc(-1, "tEXt", 4); crc = PngCrc(crc, key, klen); crc = PngCrc(crc, value, vlen); crc = Swap32(crc ^ 0xffffffff); write(fd, &crc, 4); return 12 + vlen + klen; } int writePLTE(int fd, PngColor *p, word count) { ChunkHeader header; LongWord crc; header.length = Swap32(3 * count); header.type[0] = 'P'; header.type[1] = 'L'; header.type[2] = 'T'; header.type[3] = 'E'; write(fd, &header, sizeof(header)); write(fd, p, 3 * count); crc = PngCrc(-1, "PLTE", 4); crc = PngCrc(crc, (void *)p, 3 * count); crc = Swap32(crc) ^ 0xffffffff; write(fd, &crc, 4); return 12 + 3 * count; } int writeIDAT(int fd, void *data, longword size) { ChunkHeader header; LongWord crc; header.length = Swap32(size); header.type[0] = 'I'; header.type[1] = 'D'; header.type[2] = 'A'; header.type[3] = 'T'; //header write(fd, &header, sizeof(header)); // data write(fd, data, size); // checksum crc = PngCrc(-1, "IDAT", 4); // will fail if > 64k...need to split it up. while (size) { Word t = size > 0xffff ? 0xffff : size; crc = PngCrc(crc, data, t); size -= t; data = ((char *)data) + t; } crc = Swap32(crc) ^ 0xffffffff; write(fd, &crc, 4); }