Subject: | Images from clipboard fail |
Date: | Sat, 21 Apr 2012 00:32:16 -0400 |
To: | <bug-imager [...] rt.cpan.org> |
From: | Benjamin Goldberg <ben-goldberg [...] hotmail.com> |
The following test program...
use strict;use warnings;
use Win32::GuiTest ':FUNC';
my ($win) = FindWindowLike(undef, "Command Prompt") or die "Couldn't find window\n";my $prior = SetActiveWindow($win);END { SetActiveWindow($prior) if $prior && GetActiveWindow() == $win;}SendKeys('%{PRTSCR}');
use Win32::Clipboard;my $clip = Win32::Clipboard->new->GetBitmap() or die "No BMP in clipboard";
my @header = unpack('aaVvvVVV!V!vvVVVVVV', $clip);my @hnames = qw(b m filesize res1 res2 offbits infohead_size xsize ysize planes bitcount compression size_image xres yres clr_use clr_important);die "oops" if @hnames != @header;print "$hnames[$_]:\t$header[$_]\n" for 0..$#header;
use Imager; # print "Imager loaded.\n";my $img = Imager->new;$img->read(data=>$clip, type=>'bmp') or die "Imager->read failed: ", $img->errstr();__END__
Fails, with the following output:
b: Bm: Mfilesize: 1942610res1: 0res2: 0offbits: 66infohead_size: 40xsize: 668ysize: 727planes: 1bitcount: 32compression: 3size_image: 1942544xres: 0yres: 0clr_use: 0clr_important: 0Imager->read failed: image data offset too small (66) at fail.pl line 27.
Looking through the source code on CPAN, I notice that in bmp.c, whencompression is equal to 3 (aka BI_BITFIELDS), the error producing code is reached if offbitsis less than FILEHEAD_SIZE + INFOHEAD_SIZE + 4 * 4... aka 14 + 40 + 16, or 70...
Obviously, the value 66 is less than 70, producing the message.
Since the image was produced by Windows itself, it shouldbe safe to assume that the image is well formed.
Are you certain that adding 4 * 4 to base_offset is the correct thing to do?
According to Wikipedia's file on the BMP file format:
The color table (palette) occurs in the BMP image file directly after the BMP file header, the DIB header (and after optional three red, green and blue bitmasks if the BITMAPINFOHEADER header with BI_BITFIELDS option is used). Therefore, its offset is the size of the BITMAPFILEHEADER plus the size of the DIB header (plus optional 2 bytes for the three bit masks).
Note: On Windows CE the BITMAPINFOHEADER header can be used with the BI_ALPHABITFIELDS[2] option in the biCompression member. In such case, four optional bitmasks follow the BITMAPINFOHEADER header instead of the two bitmask mentioned above, thus the color table's offset is the size of the BITMAPFILEHEADER plus the size of the BITMAPINFOHEADER header plus the 6 bytes of the four bitmasks (red, green, blue and alpha).
Maybe you should be adding "3 * 4" instead of "4 * 4" ?
I'm using Imager version .75, Windows XP, and perl -V produces:
Summary of my perl5 (revision 5 version 12 subversion 1) configuration:
Platform: osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread uname='Win32 strawberryperl 5.12.1.0 #1 Thu Jul 29 10:08:11 2010 i386' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -mms-bitfields -DPERL_MSVCRT_READFIX', optimize='-s -O2', cppflags='-DWIN32' ccversion='', gccversion='4.4.3', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"' libpth=C:\strawberry\c\lib C:\strawberry\c\i686-w64-mingw32\lib libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 libc=, so=dll, useshrplib=true, libperl=libperl512.a gnulibc_version='' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"'
Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_PERL_ATOF USE_SITECUSTOMIZE Built under MSWin32 Compiled at Jul 29 2010 16:46:09 @INC: C:/strawberry/perl/site/lib C:/strawberry/perl/vendor/lib C:/strawberry/perl/lib .