diff options
author | Tor Andersson <tor@ghostscript.com> | 2005-06-02 11:36:37 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2005-06-02 11:36:37 +0200 |
commit | 6eb3bfd3337f6d20fcd7643ce1c23cda241cf31c (patch) | |
tree | e23324eacfdca13680a823d364a2b639e9ff2c07 /samus/sa_tiff.c | |
parent | 4ad40244021880e90d670720ac4c3beeac70aebc (diff) | |
download | mupdf-6eb3bfd3337f6d20fcd7643ce1c23cda241cf31c.tar.xz |
use filters directly in tiff loader
Diffstat (limited to 'samus/sa_tiff.c')
-rw-r--r-- | samus/sa_tiff.c | 243 |
1 files changed, 165 insertions, 78 deletions
diff --git a/samus/sa_tiff.c b/samus/sa_tiff.c index 6a6db2d7..5a83f593 100644 --- a/samus/sa_tiff.c +++ b/samus/sa_tiff.c @@ -187,6 +187,137 @@ tiffdebug(sa_tiff *tiff) } static fz_error * +tiffreaduncompressed(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + printf("uncompressed %d bytes\n", len); + return nil; +} + +static fz_error * +tiffreadfiltered(sa_tiff *tiff, + unsigned char *mem, unsigned len, fz_filter *filter) +{ + fz_error *error; + fz_buffer *buf; + fz_buffer *out; + + printf("compressed %d bytes\n", len); + + error = fz_newbufferwithmemory(&buf, mem, len); + if (error) + return error; + + error = fz_newbuffer(&out, FZ_BUFSIZE); + if (error) + { + fz_dropbuffer(buf); + return error; + } + + buf->eof = 1; + + while (1) + { + error = fz_process(filter, buf, out); + + printf(" + %d bytes\n", out->wp - out->rp); + + if (error == fz_ioneedin) + { + error = fz_throw("ioerror: premature eof in filter"); + goto cleanup; + } + else if (error == fz_ioneedout) + { + if (out->wp - out->rp == 0) + { + error = fz_growbuffer(out); + if (error) + goto cleanup; + } + out->rp = out->bp; + out->wp = out->bp; + } + else if (error == fz_iodone) + { + break; + } + else + goto cleanup; + } + + return nil; + +cleanup: + fz_dropbuffer(out); + fz_dropbuffer(buf); + return error; +} + +static fz_error * +tiffreadpackbits(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + fz_error *error; + fz_filter *filter; + + error = fz_newrld(&filter, 0); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * +tiffreadcrle(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + fz_error *error; + fz_filter *filter; + fz_obj *params; + + error = fz_packobj(¶ms, "<<" + "/K 0 /EncodedByteAlign true /EndOfLine false /EndOfBlock false" + "/Columns %i /Rows %i /BlackIs1 %b" + ">>", + tiff->imagewidth, + tiff->imagelength, + tiff->photometric == 0); + if (error) + return error; + + error = fz_newfaxd(&filter, params); + fz_dropobj(params); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * +tiffreadlzw(sa_tiff *tiff, unsigned char *mem, unsigned len) +{ + fz_error *error; + fz_filter *filter; + fz_obj *params; + + error = fz_packobj(¶ms, "<</EarlyChange 0>>"); + if (error) + return error; + + error = fz_newlzwd(&filter, params); + fz_dropobj(params); + if (error) + return error; + + error = tiffreadfiltered(tiff, mem, len, filter); + fz_dropfilter(filter); + return error; +} + +static fz_error * tiffreadstrips(sa_tiff *tiff) { /* switch on compression to create a filter */ @@ -195,13 +326,11 @@ tiffreadstrips(sa_tiff *tiff) /* packbits -- nothing special (same row-padding as PDF) */ /* ccitt type 2 -- no EOL, no RTC, rows are byte-aligned */ + /* lzw -- each strip is handled separately */ + /* g3 and g4 -- each strip starts new section -- maybe can avoid? */ fz_error *error; - fz_obj *params; - fz_buffer *buf; - fz_stream *file; - fz_filter *filter; - unsigned char tmp[512]; + unsigned char *mem; int row; int strip; @@ -225,108 +354,64 @@ printf("w=%d h=%d n=%d bpc=%d ", switch (tiff->compression) { - case 1: - printf("Uncompressed "); - filter = nil; - break; - - case 2: - printf("CCITT "); - - error = fz_packobj(¶ms, "<<" - "/K 0 /EncodedByteAlign true /EndOfLine false /EndOfBlock false" - "/Columns %i /Rows %i /BlackIs1 %b" - ">>", - tiff->imagewidth, - tiff->imagelength, - tiff->photometric == 0); - if (error) - return error; - - error = fz_newfaxd(&filter, params); - fz_dropobj(params); - if (error) - return error; - break; - - case 32773: - printf("PackBits "); - error = fz_newrld(&filter, 0); - if (error) - return error; - break; - + case 1: printf("Uncompressed "); break; + case 2: printf("CCITT "); break; + case 3: printf("FaxG3"); break; + case 4: printf("FaxG4"); break; + case 5: printf("LZW "); break; + case 32773: printf("PackBits "); break; default: return fz_throw("ioerror: unknown TIFF compression: %d", tiff->compression); } printf("\n"); - /* TODO: scrap write-file and decode with filter directly to final destination */ - error = fz_newbuffer(&buf, 4096); - error = fz_openwbuffer(&file, buf); - - if (filter) - { - fz_stream *temp; - error = fz_openwfilter(&temp, filter, file); - if (error) - { - fz_dropfilter(filter); - fz_dropstream(file); - return error; - } - fz_dropstream(file); - file = temp; - } - strip = 0; for (row = 0; row < tiff->imagelength; row += tiff->rowsperstrip) { unsigned offset = tiff->stripoffsets[strip]; unsigned bytecount = tiff->stripbytecounts[strip]; - fz_seek(tiff->file, offset, 0); + mem = fz_malloc(bytecount); + if (!mem) + return fz_outofmem; - while (bytecount) + fz_seek(tiff->file, offset, 0); + len = fz_read(tiff->file, mem, bytecount); + if (len < 0) { - len = fz_read(tiff->file, tmp, MIN(bytecount, sizeof tmp)); - if (len < 0) - return fz_throw("ioerror: read failed"); - bytecount -= len; + fz_free(mem); + return fz_ioerror(tiff->file); + } - if (tiff->fillorder == 2) - { - for (i = 0; i < len; i++) - tmp[i] = bitrev[tmp[i]]; - } + if (tiff->fillorder == 2) + for (i = 0; i < len; i++) + mem[i] = bitrev[mem[i]]; - len = fz_write(file, tmp, len); - if (len < 0) - return fz_throw("ioerror: write failed"); + switch (tiff->compression) + { + case 1: error = tiffreaduncompressed(tiff, mem, len); break; + case 2: error = tiffreadcrle(tiff, mem, len); break; + //case 3: error = tiffreadg3(tiff, mem, len); break; + //case 4: error = tiffreadg4(tiff, mem, len); break; + case 5: error = tiffreadlzw(tiff, mem, len); break; + case 32773: error = tiffreadpackbits(tiff, mem, len); break; } + fz_free(mem); + strip ++; } - if (filter) - fz_dropfilter(filter); - - fz_dropstream(file); - if (tiff->photometric == 3 && tiff->colormap) { /* TODO expand RGBPal datain buf via colormap to output */ - printf(" read %d bytes (indexed)\n", buf->wp - buf->rp); } else { /* TODO copy buf to output */ - printf(" read %d bytes\n", buf->wp - buf->rp); } - fz_dropbuffer(buf); - return nil; } @@ -499,7 +584,9 @@ sa_readtiff(fz_stream *file) n = fz_readall(&buf, file); if (n < 0) - return fz_throw("ioerror: readall failed"); + return fz_ioerror(file); + +printf("readall -> %d\n", n); error = fz_openrbuffer(&newfile, buf); if (error) |