#include #include "tiff.h" #include "video.h" /*** T I F F ***/ typedef struct { unsigned int endian; unsigned int version; unsigned long ifdOffset; } TifHeader_t; #define TIF_WIDTH 256 #define TIF_HEIGHT 257 #define TIF_BITSPERSAMPLE 258 #define TIF_COMPRESSION 259 #define TIF_STRIPOFFSETS 273 #define TIF_ROWSPERSTRIP 278 typedef struct { unsigned int id; unsigned int dataType; unsigned long dataCount; unsigned long dataOffset; } TifTag_t; TifImageMeta_t tifLoadMeta(FILE *f) { TifImageMeta_t meta = {0, 0, 0, 0, 0}; TifHeader_t header; TifTag_t tag; unsigned int i, tagCount; fseek(f, 0, SEEK_SET); fread(&header, 8, 1, f); if (header.endian != 0x4949 || header.version != 0x2a) { goto fail; } fseek(f, header.ifdOffset, SEEK_SET); fread(&tagCount, 2, 1, f); for (i = 0; i < tagCount; i ++) { fread(&tag, 12, 1, f); if (tag.id == TIF_WIDTH) { meta.width = tag.dataOffset; } else if (tag.id == TIF_HEIGHT) { meta.height = tag.dataOffset; } else if (tag.id == TIF_BITSPERSAMPLE) { if (tag.dataOffset != 4) goto fail; } else if (tag.id == TIF_COMPRESSION) { if (tag.dataOffset != 1) goto fail; } else if (tag.id == TIF_STRIPOFFSETS) { meta.stripCount = tag.dataCount; meta.stripOffsets = tag.dataOffset; } else if (tag.id == TIF_ROWSPERSTRIP) { meta.rowsPerStrip = tag.dataOffset; } } return meta; fail: meta.stripCount = 0; return meta; } int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, unsigned int w) { int istrip; int irow; int ipixelpair; int y = 0; unsigned long offset; unsigned char rowData[MAX_WIDTH >> 1]; volatile unsigned char far *out = &VID[vidOffset]; unsigned char b, g, r, i; if (meta.width > MAX_WIDTH || (meta.width % 8) != 0) { return 0; } setWriteMode(0); for (istrip = 0; istrip < meta.stripCount; istrip ++) { fseek(f, meta.stripOffsets + (istrip << 2), SEEK_SET); fread(&offset, 4, 1, f); fseek(f, offset, SEEK_SET); for (irow = 0; irow < meta.rowsPerStrip; irow ++) { int ipixelpairLim = meta.width >> 1; fread(rowData, 1, ipixelpairLim, f); b = g = r = i = 0; for (ipixelpair = 0; ipixelpair < ipixelpairLim; ipixelpair ++) { unsigned char pixelpair = rowData[ipixelpair]; int bpair = (pixelpair & 0x01) | (pixelpair & 0x10) >> 3; int gpair = (pixelpair & 0x02) >> 1 | (pixelpair & 0x20) >> 4; int rpair = (pixelpair & 0x04) >> 2 | (pixelpair & 0x40) >> 5; int ipair = (pixelpair & 0x08) >> 3 | (pixelpair & 0x80) >> 6; int shift = (3 - (ipixelpair % 4)) << 1; b |= bpair << shift; g |= gpair << shift; r |= rpair << shift; i |= ipair << shift; if (shift == 0 || ipixelpair == ipixelpairLim - 1) { // todo: use write mode 2, this is slooww setPlane(PLANE_B); *out = b; setPlane(PLANE_R); *out = r; setPlane(PLANE_G); *out = g; setPlane(PLANE_I); *out = i; out ++; b = g = r = i = 0; } } y++; if (y == maxY) { return y; } out += (w - meta.width) >> 3; } } return y; } int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int far *planeBuf, int maxY, int yRepeat, int planes) { int istrip; int irow; int ipixelpair; int y = 0; unsigned long offset; unsigned char rowData[MAX_WIDTH >> 1]; unsigned int planeStride = (meta.width >> 4) * yRepeat; unsigned int far *bp = planeBuf; unsigned int far *gp = bp + planeStride; unsigned int far *rp = gp + planeStride; unsigned int far *ip = rp + planeStride; unsigned int far *mp = ip + planeStride; unsigned int bv, gv, rv, iv; if (meta.width > MAX_WIDTH || (meta.width % 16) != 0 || planes < 4 || planes > 5) { return 0; } for (istrip = 0; istrip < meta.stripCount; istrip ++) { fseek(f, meta.stripOffsets + (istrip << 2), SEEK_SET); fread(&offset, 4, 1, f); fseek(f, offset, SEEK_SET); for (irow = 0; irow < meta.rowsPerStrip; irow ++) { int ipixelpairLim = meta.width >> 1; fread(rowData, 1, ipixelpairLim, f); bv = gv = rv = iv = 0; for (ipixelpair = 0; ipixelpair < ipixelpairLim; ipixelpair ++) { unsigned char pixelpair = rowData[ipixelpair]; int bpair = (pixelpair & 0x01) | (pixelpair & 0x10) >> 3; int gpair = (pixelpair & 0x02) >> 1 | (pixelpair & 0x20) >> 4; int rpair = (pixelpair & 0x04) >> 2 | (pixelpair & 0x40) >> 5; int ipair = (pixelpair & 0x08) >> 3 | (pixelpair & 0x80) >> 6; int shift = (7 - (ipixelpair % 8)) << 1; bv |= bpair << shift; gv |= gpair << shift; rv |= rpair << shift; iv |= ipair << shift; if (shift == 0 || ipixelpair == ipixelpairLim - 1) { *bp++ = bv; *gp++ = gv; *rp++ = rv; *ip++ = iv; if (planes == 5) { iv = ~(bv & gv & rv & iv); *mp++ = iv; } bv = gv = rv = iv = 0; } } y++; if (y == maxY) { return y; } if (y % yRepeat == 0) { bp += planeStride * (planes - 1); gp += planeStride * (planes - 1); rp += planeStride * (planes - 1); ip += planeStride * (planes - 1); mp += planeStride * (planes - 1); } } } return y; }