More support for autodetection of formats, still some error comes up in
authorArnar Mar Hrafnkelsson <addi@cpan.org>
Tue, 20 Aug 2002 00:54:15 +0000 (00:54 +0000)
committerArnar Mar Hrafnkelsson <addi@cpan.org>
Tue, 20 Aug 2002 00:54:15 +0000 (00:54 +0000)
t50basicoo.t.

Imager.pm
image.c
image.h
t/t101jpeg.t
tga.c

index 2d8b90a..d358cf2 100644 (file)
--- 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 d327fec..244f128 100644 (file)
--- 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<flush> 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; i<sizeof(formats)/sizeof(formats[0]); i++) { 
-    int c = !strncmp(formats[i].magic, head, strlen(formats[i].magic));
+    int c;
+    ssize_t len = strlen(formats[i].magic);
+    if (rc<len) continue;
+    c = !strncmp(formats[i].magic, head, len);
     if (c) {
       match = formats[i].name;
       break;
     }
   }
 
-  data->seekcb(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 b21a20e..9ca74a3 100644 (file)
--- 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);
 
index 3b55768..2a4653e 100644 (file)
@@ -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 bd57418..80b6066 100644 (file)
--- 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;