From 84e51293e6a1c380f80f5579fcf521bb655c2652 Mon Sep 17 00:00:00 2001 From: Arnar Mar Hrafnkelsson Date: Tue, 20 Aug 2002 00:54:15 +0000 Subject: [PATCH] More support for autodetection of formats, still some error comes up in t50basicoo.t. --- Imager.pm | 33 ++++++++++++++------------------- image.c | 40 ++++++++++++++++++++++++++++++++-------- image.h | 2 ++ t/t101jpeg.t | 2 ++ tga.c | 34 +++++++++++++++++++++++++++++++++- 5 files changed, 83 insertions(+), 28 deletions(-) diff --git a/Imager.pm b/Imager.pm index 2d8b90af..d358cf27 100644 --- a/Imager.pm +++ b/Imager.pm @@ -890,14 +890,14 @@ sub settag { } } -my @needseekcb = qw/tiff/; -my %needseekcb = map { $_, $_ } @needseekcb; - sub _get_reader_io { - my ($self, $input, $type) = @_; + my ($self, $input) = @_; - if ($input->{fd}) { + if ($input->{io}) { + return $input->{io}, undef; + } + elsif ($input->{fd}) { return io_new_fd($input->{fd}); } elsif ($input->{fh}) { @@ -921,8 +921,8 @@ sub _get_reader_io { return io_new_buffer($input->{data}); } elsif ($input->{callback} || $input->{readcb}) { - if ($needseekcb{$type} && !$input->{seekcb}) { - $self->_set_error("Format $type needs a seekcb parameter"); + if (!$input->{seekcb}) { + $self->_set_error("Need a seekcb parameter"); } if ($input->{maxbuffer}) { return io_new_cb($input->{writecb}, @@ -1011,23 +1011,18 @@ sub read { # has been there for half a year dude. # Look, i just work here, ok? - if (!$input{'type'} and $input{file}) { - $input{'type'}=$FORMATGUESS->($input{file}); - } + my ($IO, $fh) = $self->_get_reader_io(\%input) or return; + unless ($input{'type'}) { - $self->_set_error('type parameter missing and not possible to guess from extension'); + $input{'type'} = i_test_format_probe($IO, -1); + } + + unless ($input{'type'}) { + $self->_set_error('type parameter missing and not possible to guess from extension'); return undef; } - if (!$formats{$input{'type'}}) { - $self->{ERRSTR}='format not supported'; return undef; - } - - my %iolready=(jpeg=>1, png=>1, tiff=>1, pnm=>1, raw=>1, bmp=>1, tga=>1, rgb=>1, gif=>1); # Setup data source - my ($IO, $fh) = $self->_get_reader_io(\%input, $input{'type'}) - or return; - if ( $input{'type'} eq 'jpeg' ) { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_wiol( $IO ); if ( !defined($self->{IMG}) ) { diff --git a/image.c b/image.c index d327fec1..244f1289 100644 --- a/image.c +++ b/image.c @@ -2131,6 +2131,20 @@ int i_free_gen_write_data(i_gen_write_data *info, int flush) +/* +=item i_test_format_probe(io_glue *data, int length) + +Cleans up the write buffer. + +Will flush any left-over data if I is non-zero. + +Returns non-zero if flush is zero or if info->cb() returns non-zero. + +Return zero only if flush is non-zero and info->cb() returns zero. +ie. if it fails. + +=cut +*/ char * @@ -2143,33 +2157,43 @@ i_test_format_probe(io_glue *data, int length) { {"\xFF\xD8", "jpeg"}, {"GIF87a", "gif"}, {"GIF89a", "gif"}, + {"MM\0*", "tiff"}, + {"II*\0", "tiff"}, + {"BM", "bmp"}, + {"\x89PNG\x0d\x0a\x1a\x0a", "png"}, {"P1", "pnm"}, {"P2", "pnm"}, {"P3", "pnm"}, {"P4", "pnm"}, {"P5", "pnm"}, {"P6", "pnm"}, - {"MM\0*", "tiff"}, - {"II*\0", "tiff"}, - {"BM", "bmp"}, - {"\x89PNG\x0d\x0a\x1a\x0a", "png"} }; unsigned int i; - char head[8]; + char head[18]; char *match = NULL; + ssize_t rc; io_glue_commit_types(data); - data->readcb(data, head, 8); + rc = data->readcb(data, head, 18); + if (rc == -1) return NULL; + data->seekcb(data, -rc, SEEK_CUR); for(i=0; iseekcb(data, -8, SEEK_CUR); + + + if (!match && + (rc == 18) && + tga_header_verify(head)) return "tga"; return match; } diff --git a/image.h b/image.h index b21a20e3..9ca74a3c 100644 --- a/image.h +++ b/image.h @@ -563,6 +563,8 @@ undef_int i_writeppm_wiol(i_img *im, io_glue *ig); extern int i_writebmp_wiol(i_img *im, io_glue *ig); extern i_img *i_readbmp_wiol(io_glue *ig); +int tga_header_verify(unsigned char headbuf[18]); + i_img * i_readtga_wiol(io_glue *ig, int length); undef_int i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen); diff --git a/t/t101jpeg.t b/t/t101jpeg.t index 3b557684..2a4653e8 100644 --- a/t/t101jpeg.t +++ b/t/t101jpeg.t @@ -44,10 +44,12 @@ if (!i_has_format("jpeg")) { $diff < 10000 or print "not "; print "ok 3\n"; + Imager::log_entry("Starting 4\n", 1); my $imoo = Imager->new; $imoo->read(file=>'testout/t101.jpg') or print "not "; print "ok 4\n"; $imoo->write(file=>'testout/t101_oo.jpg') or print "not "; + Imager::log_entry("Starting 5\n", 1); print "ok 5\n"; my $oocmp = Imager->new; $oocmp->read(file=>'testout/t101_oo.jpg') or print "not "; diff --git a/tga.c b/tga.c index bd574187..80b6066d 100644 --- a/tga.c +++ b/tga.c @@ -321,6 +321,36 @@ tga_header_unpack(tga_header *header, unsigned char headbuf[18]) { } + +int +tga_header_verify(unsigned char headbuf[18]) { + tga_header header; + tga_header_unpack(&header, headbuf); + switch (header.datatypecode) { + default: + printf("bad typecode!\n"); + return 0; + case 0: + case 1: /* Uncompressed, color-mapped images */ + case 2: /* Uncompressed, rgb images */ + case 3: /* Uncompressed, grayscale images */ + case 9: /* Compressed, color-mapped images */ + case 10: /* Compressed, rgb images */ + case 11: /* Compressed, grayscale images */ + } + + switch (header.colourmaptype) { + default: + printf("bad colourmaptype!\n"); + return 0; + case 0: + case 1: + } + + return 1; +} + + /* =item tga_header_pack(header, headbuf) @@ -388,9 +418,11 @@ tga_source_read(tga_source *s, unsigned char *buf, size_t pixels) { s->len = (s->hdr &~(1<<7))+1; s->state = (s->hdr & (1<<7)) ? Rle : Raw; { +/* static cnt = 0; printf("%04d %s: %d\n", cnt++, s->state==Rle?"RLE":"RAW", s->len); - } + */ + } if (s->state == Rle && s->ig->readcb(s->ig, s->cval, s->bytepp) != s->bytepp) return 0; break; -- 2.39.5