Codebase list libimager-perl / 7cffb47
Imported Upstream version 0.86+dfsg gregor herrmann 12 years ago
79 changed file(s) with 4449 addition(s) and 1728 deletion(s). Raw diff Collapse all Expand all
00 Imager release history. Older releases can be found in Changes.old
1
2 Imager 0.86 - 31 Oct 2011
3 ===========
4
5 - improve error reporting for W32 tests
6
7 Imager 0.85_02 - 24 Oct 2011
8 ==============
9
10 Bug fixes:
11
12 - eliminate unused i_gif_opts type (clean-up)
13 https://rt.cpan.org/Ticket/Display.html?id=69245
14
15 - fix combine=0 fill color anti-aliasing on the double/sample path
16 https://rt.cpan.org/Ticket/Display.html?id=71309
17
18 - make default text color non-transparent
19 https://rt.cpan.org/Ticket/Display.html?id=71469
20
21 - apply the last of the Debian unforwarded spelling fixes
22 https://rt.cpan.org/Ticket/Display.html?id=70656
23
24 - the log() method used its message parameter as a C level format
25 string.
26 https://rt.cpan.org/Ticket/Display.html?id=71653
27
28 - provide our own STRLEN typemap entry for older perls.
29 https://rt.cpan.org/Ticket/Display.html?id=71641
30
31 - add extra ppport.h configuration to support older perls.
32
33 - depend on Scalar::Util, since we use it and older perls don't have
34 it.
35
36 - add overloaded eq to Imager::Matrix2d, since older perls don't seem
37 to synthesize it from overloaded "".
38
39 - use T1_StrError() for error messages on modern libt1
40 https://rt.cpan.org/Ticket/Display.html?id=69879
41
42 - actually load the font rather than just adding it to the catalog on
43 creation.
44
45 - Imager::Font->new now produces better error messages for the T1
46 engine.
47
48 - the font has_chars() method now returns perl's true and false
49 values in list context rather than integers, which should be more
50 efficient.
51 https://rt.cpan.org/Ticket/Display.html?id=69158
52
53 - the btm data structure used by the flood_fill code is now
54 initialized more efficiently.
55 https://rt.cpan.org/Ticket/Display.html?id=68994
56
57 - updated the Thanks list in README
58 https://rt.cpan.org/Ticket/Display.html?id=71607
59
60 - check there's at least one coefficient for the convolution filter
61 https://rt.cpan.org/Ticket/Display.html?id=68993
62
63 - make the APIRef synopsis ordering consistent, older versions of
64 perl could order it differently.
65 https://rt.cpan.org/Ticket/Display.html?id=71675
66
67 - we rely on Config.pm's d_vsnprintf as to whether we use
68 vsnprintf/snprintf, which is defined in the Win32 Config.pm even
69 though it only has _ prefixed versions of these. Define our own
70 prefixed names on Win32.
71 https://rt.cpan.org/Ticket/Display.html?id=71642
72
73 - fix library detection with MSVC
74
75 - search a few more library directories, so EU::MM doesn't discard
76 them. Hopefully fixes:
77 https://rt.cpan.org/Ticket/Display.html?id=71643
78
79 Imager 0.85_01 - 10 Oct 2011
80 ==============
81
82 - add simple tests for the Imager::Test test_image generators
83
84 - io_glue I/O buffering re-work:
85
86 - reorganize io_glue to do it's own buffering by default
87
88 - the unbuffered functions are available as i_io_raw_read() (or
89 raw_read() from perl) etc but are not recommended for typical
90 use.
91
92 - use the new i_io_peekn() when checking for file magic to avoid
93 seek, allowing Imager to detect the file type and read the file
94 from an unseekable stream (for formats that don't use random
95 access)
96
97 - added several new I/O layer API functions.
98
99 - fix the TGA performance problem, most noticably on Win32
100 https://rt.cpan.org/Ticket/Display.html?id=70037
101
102 - TIFF now uses wrapper functions of the correct types to avoid casts
103 https://rt.cpan.org/Ticket/Display.html?id=69912
104
105 - the callback IO object did its own buffering, controlled by the
106 maxbuffer parameter supplied to the read() and write() methods.
107 This buffering has been removed, to avoid redundancy with the
108 common io_glue buffering. This also avoids a bug in that code
109 which could rarely pass a zero length to the read callback and
110 then panic about the result.
111
112 - the callback IO object now tests the result of calling the close
113 callback, which should return true for success.
114
115 - the PNM reader did its own buffering. This buffering has been
116 removed to avoid redundancy with the common io_glue buffering.
117
118 - previously the read handlers for fd and callback I/O layers would
119 call the underlying interface (POSIX read or your supplied callback)
120 until it filled the buffer. It now only makes one call.
121
122 - added public constructors for I/O layer objects (see Imager::IO)
123
124 - all core file handlers now use the i_io_foo() wrappers to gain
125 access to buffered I/O rather than calling the I/O layer
126 callbacks directly.
127
128 - all core file handlers now check for error on close.
129
130 - Backward compatibility: if you hava custom file handlers, you can
131 use i_io_write() etc since they're available as macros in older
132 versions of Imager.
133
134 - eliminate the final remnants of io_glue_commit_types().
135
136 - bump IMAGER_API_VERSION, since the above may break assumptions.
137
138 - removed the long unused i_gen_reader() and i_gen_writer() utility
139 functions.
1140
2141 Imager 0.85 - 29 Aug 2011
3142 ===========
44 @ISA = qw(Imager::Font);
55
66 BEGIN {
7 $VERSION = "0.82";
7 $VERSION = "0.83";
88
99 eval {
1010 require XSLoader;
2121
2222 sub new {
2323 my $class = shift;
24 my %hsh=(color=>Imager::Color->new(255,0,0,0),
24 my %hsh=(color=>Imager::Color->new(255,0,0,255),
2525 size=>15,
2626 @_);
2727
227227 if (GIMME_V == G_ARRAY) {
228228 EXTEND(SP, count);
229229 for (i = 0; i < count; ++i) {
230 PUSHs(sv_2mortal(newSViv(work[i])));
230 PUSHs(boolSV(work[i]));
231231 }
232232 }
233233 else {
00 #!perl -w
11 use strict;
2 use Test::More tests => 189;
2 use Test::More tests => 193;
33 use Cwd qw(getcwd abs_path);
44
55 use Imager qw(:all);
66
7 use Imager::Test qw(diff_text_with_nul is_color3);
7 use Imager::Test qw(diff_text_with_nul is_color3 is_color4 isnt_image);
88
99 -d "testout" or mkdir "testout";
1010
2020
2121 my $fontname=$ENV{'TTFONTTEST'} || $deffont;
2222
23 -f $fontname or skip("cannot find fontfile $fontname", 188);
23 -f $fontname or skip("cannot find fontfile $fontname", 189);
2424
2525
2626 my $bgcolor=i_color_new(255,0,0,0);
514514 ok($font, "found font by drive relative path")
515515 or print "# path $drive_path\n";
516516 }
517
517 { # RT 71469
518 my $font1 = Imager::Font->new(file => $deffont, type => "ft2", index => 0);
519 my $font2 = Imager::Font::FT2->new(file => $deffont, index => 0);
520
521 for my $font ($font1, $font2) {
522 print "# ", join(",", $font->{color}->rgba), "\n";
523
524 my $im = Imager->new(xsize => 20, ysize => 20, channels => 4);
525
526 ok($im->string(text => "T", font => $font, y => 15),
527 "draw with default color")
528 or print "# ", $im->errstr, "\n";
529 my $work = Imager->new(xsize => 20, ysize => 20);
530 my $cmp = $work->copy;
531 $work->rubthrough(src => $im);
532 isnt_image($work, $cmp, "make sure something was drawn");
533 }
534 }
518535 }
519536
520537 sub align_test {
33 use vars qw($VERSION @ISA);
44
55 BEGIN {
6 $VERSION = "0.81";
6 $VERSION = "0.82";
77
88 eval {
99 require XSLoader;
3737 $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
3838
3939 # Imager required configure through use
40 my @Imager_req = ( Imager => "0.85" );
40 my @Imager_req = ( Imager => "0.86" );
4141 if ($MM_ver >= 6.46) {
4242 $opts{META_MERGE} =
4343 {
851851 io_glue_read_cb(GifFileType *gft, GifByteType *buf, int length) {
852852 io_glue *ig = (io_glue *)gft->UserData;
853853
854 return ig->readcb(ig, buf, length);
854 return i_io_read(ig, buf, length);
855855 }
856856
857857 i_img *
17711771 io_glue_write_cb(GifFileType *gft, const GifByteType *data, int length) {
17721772 io_glue *ig = (io_glue *)gft->UserData;
17731773
1774 return ig->writecb(ig, data, length);
1774 return i_io_write(ig, data, length);
17751775 }
17761776
17771777
17991799
18001800 result = i_writegif_low(quant, GifFile, imgs, count);
18011801
1802 ig->closecb(ig);
1802 if (i_io_close(ig))
1803 return 0;
18031804
18041805 return result;
18051806 }
1313 $|=1;
1414 use Test::More;
1515 use Imager qw(:all);
16 use Imager::Test qw(is_color3 test_image test_image_raw);
16 use Imager::Test qw(is_color3 test_image test_image_raw test_image_mono);
1717 use Imager::File::GIF;
1818
1919 use Carp 'confess';
2323
2424 init_log("testout/t105gif.log",1);
2525
26 plan tests => 144;
26 plan tests => 146;
2727
2828 my $green=i_color_new(0,255,0,255);
2929 my $blue=i_color_new(0,0,255,255);
736736 my ($im) = Imager->read_multi(file => "testimg/zerocomm.gif");
737737 ok($im, "read image with zero-length extension");
738738 }
739
740
741 { # check close failures are handled correctly
742 my $im = test_image_mono();
743 my $fail_close = sub {
744 Imager::i_push_error(0, "synthetic close failure");
745 return 0;
746 };
747 ok(!$im->write(type => "gif", callback => sub { 1 },
748 closecb => $fail_close),
749 "check failing close fails");
750 like($im->errstr, qr/synthetic close failure/,
751 "check error message");
752 }
753
739754
740755 sub test_readgif_cb {
741756 my ($size) = @_;
0 #include "imext.h"
01 #include "msicon.h"
12 #include <string.h>
23 #include <stdlib.h>
00 #ifndef IMAGER_MSICON_H_
11 #define IMAGER_MSICON_H_
22
3 #include "iolayer.h"
3 #include "iolayert.h"
44
55 typedef struct ico_reader_tag ico_reader_t;
66
00 #!perl -w
11 use strict;
2 use Test::More tests => 100;
3 use Imager::Test qw(is_image);
2 use Test::More tests => 102;
3 use Imager::Test qw(is_image test_image);
44
55 BEGIN { use_ok('Imager::File::ICO'); }
66
370370 $vs->box(filled => 1, color => '#333366');
371371 is_image($im, $vs, "check we got the right colors");
372372 }
373
374
375 { # check close failures are handled correctly
376 my $im = test_image();
377 my $fail_close = sub {
378 Imager::i_push_error(0, "synthetic close failure");
379 return 0;
380 };
381 ok(!$im->write(type => "ico", callback => sub { 1 },
382 closecb => $fail_close),
383 "check failing close fails");
384 like($im->errstr, qr/synthetic close failure/,
385 "check error message");
386 }
7676 # low level write failure tests for each entry point (fail on write)
7777 {
7878 my $im = Imager->new(xsize => 10, ysize => 10);
79 ok(!$im->write(callback => \&write_failure, maxbuffer => 1, type=>'ico'),
79 my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
80 $io->set_buffered(0);
81 ok(!$im->write(io => $io, type=>'ico'),
8082 "low level write failure (ico)");
8183 is($im->errstr, "Write failure: synthetic error", "check message");
8284 }
8385
8486 {
8587 my $im = Imager->new(xsize => 10, ysize => 10);
86 ok(!$im->write(callback => \&write_failure, maxbuffer => 1, type=>'cur'),
88 my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
89 $io->set_buffered(0);
90 ok(!$im->write(io => $io, type=>'cur'),
8791 "low level write failure (cur)");
8892 is($im->errstr, "Write failure: synthetic error", "check message");
8993 }
9094
9195 {
9296 my $im = Imager->new(xsize => 10, ysize => 10);
93 ok(!Imager->write_multi({ callback => \&write_failure, maxbuffer => 1, type=>'ico' }, $im, $im),
97 my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
98 $io->set_buffered(0);
99 ok(!Imager->write_multi({ io => $io, type=>'ico' }, $im, $im),
94100 "low level write_multi failure (ico)");
95101 is(Imager->errstr, "Write failure: synthetic error", "check message");
96102 Imager->_set_error('');
98104
99105 {
100106 my $im = Imager->new(xsize => 10, ysize => 10);
101 ok(!Imager->write_multi({ callback => \&write_failure, maxbuffer => 1, type=>'cur' }, $im, $im),
107 my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
108 $io->set_buffered(0);
109 ok(!Imager->write_multi({ io => $io, type=>'cur' }, $im, $im),
102110 "low level write_multi failure (cur)");
103111 is(Imager->errstr, "Write failure: synthetic error", "check message");
104112 Imager->_set_error('');
106114
107115 {
108116 my $im = Imager->new(xsize => 10, ysize => 10);
109 ok(!$im->write(type => 'ico', callback => limited_write(6), maxbuffer => 1),
117 ok(!$im->write(type => 'ico', io => limited_write_io(6)),
110118 "second write (resource) should fail (ico)");
111119 is($im->errstr, "Write failure: limit reached", "check message");
112120 $im->_set_error('');
113121
114 ok(!$im->write(type => 'cur', callback => limited_write(6), maxbuffer => 1),
122 ok(!$im->write(type => 'cur', io => limited_write_io(6)),
115123 "second (resource) write should fail (cur)");
116124 is($im->errstr, "Write failure: limit reached", "check message");
117125 $im->_set_error('');
118126
119 ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
127 ok(!$im->write(type => 'ico', io => limited_write_io(22)),
120128 "third write (bmi) should fail (32-bit)");
121129 is($im->errstr, "Write failure: limit reached", "check message");
122130 $im->_set_error('');
123131
124 ok(!$im->write(type => 'ico', callback => limited_write(62), maxbuffer => 1),
132 ok(!$im->write(type => 'ico', io => limited_write_io(62)),
125133 "fourth write (data) should fail (32-bit)");
126134 is($im->errstr, "Write failure: limit reached", "check message");
127135 $im->_set_error('');
128136
129 ok(!$im->write(type => 'ico', callback => limited_write(462), maxbuffer => 1),
137 ok(!$im->write(type => 'ico', io => limited_write_io(462)),
130138 "mask write should fail (32-bit)");
131139 is($im->errstr, "Write failure: limit reached", "check message");
132140 }
138146 $im->addcolors(colors => [ $red, $blue ]);
139147 $im->box(filled => 1, color => $red, ymax => 5);
140148 $im->box(filled => 1, color => $blue, ymin => 6);
141 ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
149 ok(!$im->write(type => 'ico', io => limited_write_io(22)),
142150 "third write (bmi) should fail (1-bit)");
143151 is($im->errstr, "Write failure: limit reached", "check message");
144152
145 ok(!$im->write(type => 'ico', callback => limited_write(66), maxbuffer => 1),
153 ok(!$im->write(type => 'ico', io => limited_write_io(66)),
146154 "fourth write (palette) should fail (1-bit)");
147155 is($im->errstr, "Write failure: limit reached", "check message");
148 ok(!$im->write(type => 'ico', callback => limited_write(74), maxbuffer => 1),
156 ok(!$im->write(type => 'ico', io => limited_write_io(74)),
149157 "fifth write (image) should fail (1-bit)");
150158 is($im->errstr, "Write failure: limit reached", "check message");
151159 my $data;
164172 $im->addcolors(colors => [ ($red, $blue) x 8 ]);
165173 $im->box(filled => 1, color => $red, ymax => 5);
166174 $im->box(filled => 1, color => $blue, ymin => 6);
167 ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
175 ok(!$im->write(type => 'ico', io => limited_write_io(22)),
168176 "third write (bmi) should fail (4-bit)");
169177 is($im->errstr, "Write failure: limit reached", "check message");
170178
171 ok(!$im->write(type => 'ico', callback => limited_write(66), maxbuffer => 1),
179 ok(!$im->write(type => 'ico', io => limited_write_io(66)),
172180 "fourth write (palette) should fail (4-bit)");
173181 is($im->errstr, "Write failure: limit reached", "check message");
174 ok(!$im->write(type => 'ico', callback => limited_write(130), maxbuffer => 1),
182 ok(!$im->write(type => 'ico', io => limited_write_io(130)),
175183 "fifth write (image) should fail (4-bit)");
176184 is($im->errstr, "Write failure: limit reached", "check message");
177185 my $data;
190198 $im->addcolors(colors => [ ($red, $blue) x 9 ]);
191199 $im->box(filled => 1, color => $red, ymax => 5);
192200 $im->box(filled => 1, color => $blue, ymin => 6);
193 ok(!$im->write(type => 'ico', callback => limited_write(22), maxbuffer => 1),
201 ok(!$im->write(type => 'ico', io => limited_write_io(22)),
194202 "third write (bmi) should fail (8-bit)");
195203 is($im->errstr, "Write failure: limit reached", "check message");
196204
197 ok(!$im->write(type => 'ico', callback => limited_write(62), maxbuffer => 1),
205 ok(!$im->write(type => 'ico', io => limited_write_io(62)),
198206 "fourth write (palette) should fail (8-bit)");
199207 is($im->errstr, "Write failure: limit reached", "check message");
200 ok(!$im->write(type => 'ico', callback => limited_write(62 + 1024), maxbuffer => 1),
208 ok(!$im->write(type => 'ico', io => limited_write_io(62 + 1024)),
201209 "fifth write (image) should fail (8-bit)");
202210 is($im->errstr, "Write failure: limit reached", "check message");
203 ok(!$im->write(type => 'ico', callback => limited_write(62 + 1024 + 10), maxbuffer => 1),
211 ok(!$im->write(type => 'ico', io => limited_write_io(62 + 1024 + 10)),
204212 "sixth write (zeroes) should fail (8-bit)");
205213 is($im->errstr, "Write failure: limit reached", "check message");
206214 my $data;
217225 print "# synthesized write failure\n";
218226 Imager::i_push_error(0, "synthetic error");
219227 return;
228 }
229
230 sub limited_write_io {
231 my ($limit) = @_;
232
233 my $io = Imager::io_new_cb(limited_write($limit), undef, undef, undef, 1);
234 $io->set_buffered(0);
235
236 return $io;
220237 }
221238
222239 sub limited_write {
147147 if ($ex_version < 5.57) {
148148 @ISA = qw(Exporter);
149149 }
150 $VERSION = '0.85';
150 $VERSION = '0.86';
151151 eval {
152152 require XSLoader;
153153 XSLoader::load(Imager => $VERSION);
13371337 sub _get_writer_io {
13381338 my ($self, $input) = @_;
13391339
1340 my $buffered = exists $input->{buffered} ? $input->{buffered} : 1;
1341
1342 my $io;
1343 my @extras;
13401344 if ($input->{io}) {
1341 return $input->{io};
1345 $io = $input->{io};
13421346 }
13431347 elsif ($input->{fd}) {
1344 return io_new_fd($input->{fd});
1348 $io = io_new_fd($input->{fd});
13451349 }
13461350 elsif ($input->{fh}) {
13471351 my $fd = fileno($input->{fh});
13541358 # flush anything that's buffered, and make sure anything else is flushed
13551359 $| = 1;
13561360 select($oldfh);
1357 return io_new_fd($fd);
1361 $io = io_new_fd($fd);
13581362 }
13591363 elsif ($input->{file}) {
13601364 my $fh = new IO::File($input->{file},"w+");
13631367 return;
13641368 }
13651369 binmode($fh) or die;
1366 return (io_new_fd(fileno($fh)), $fh);
1370 $io = io_new_fd(fileno($fh));
1371 push @extras, $fh;
13671372 }
13681373 elsif ($input->{data}) {
1369 return io_new_bufchain();
1374 $io = io_new_bufchain();
13701375 }
13711376 elsif ($input->{callback} || $input->{writecb}) {
1372 if ($input->{maxbuffer}) {
1373 return io_new_cb($input->{callback} || $input->{writecb},
1374 $input->{readcb},
1375 $input->{seekcb}, $input->{closecb},
1376 $input->{maxbuffer});
1377 }
1378 else {
1379 return io_new_cb($input->{callback} || $input->{writecb},
1380 $input->{readcb},
1381 $input->{seekcb}, $input->{closecb});
1382 }
1377 if ($input->{maxbuffer} && $input->{maxbuffer} == 1) {
1378 $buffered = 0;
1379 }
1380 $io = io_new_cb($input->{callback} || $input->{writecb},
1381 $input->{readcb},
1382 $input->{seekcb}, $input->{closecb});
13831383 }
13841384 else {
13851385 $self->_set_error("file/fd/fh/data/callback parameter missing");
13861386 return;
13871387 }
1388
1389 unless ($buffered) {
1390 $io->set_buffered(0);
1391 }
1392
1393 return ($io, @extras);
13881394 }
13891395
13901396 # Read an image from file
43444350 compose() - L<Imager::Transformations/compose()> - compose one image
43454351 over another.
43464352
4347 convert() - L<Imager::Transformations/"Color transformations"> -
4348 transform the color space
4353 convert() - L<Imager::Transformations/convert()> - transform the color
4354 space
43494355
43504356 copy() - L<Imager::Transformations/copy()> - make a duplicate of an
43514357 image
43574363
43584364 deltag() - L<Imager::ImageTypes/deltag()> - delete image tags
43594365
4360 difference() - L<Imager::Filters/"Image Difference"> - produce a
4361 difference images from two input images.
4362
4363 errstr() - L</"Basic Overview"> - the error from the last failed
4364 operation.
4365
4366 filter() - L<Imager::Filters> - image filtering
4366 difference() - L<Imager::Filters/difference()> - produce a difference
4367 images from two input images.
4368
4369 errstr() - L</errstr()> - the error from the last failed operation.
4370
4371 filter() - L<Imager::Filters/filter()> - image filtering
43674372
43684373 findcolor() - L<Imager::ImageTypes/findcolor()> - search the image
43694374 palette, if it has one
44664471
44674472 preload() - L<Imager::Files/preload()>
44684473
4469 read() - L<Imager::Files> - read a single image from an image file
4470
4471 read_multi() - L<Imager::Files> - read multiple images from an image
4474 read() - L<Imager::Files/read()> - read a single image from an image file
4475
4476 read_multi() - L<Imager::Files/read_multi()> - read multiple images from an image
44724477 file
44734478
44744479 read_types() - L<Imager::Files/read_types()> - list image types Imager
45324537 virtual() - L<Imager::ImageTypes/virtual()> - whether the image has it's own
45334538 data
45344539
4535 write() - L<Imager::Files> - write an image to a file
4536
4537 write_multi() - L<Imager::Files> - write multiple image to an image
4540 write() - L<Imager::Files/write()> - write an image to a file
4541
4542 write_multi() - L<Imager::Files/write_multi()> - write multiple image to an image
45384543 file.
45394544
45404545 write_types() - L<Imager::Files/read_types()> - list image types Imager
47824787
47834788 =head2 Patches
47844789
4785 I accept patches, preferably against the main branch in subversion.
4786 You should include an explanation of the reason for why the patch is
4787 needed or useful.
4790 I accept patches, preferably against the master branch in git. Please
4791 include an explanation of the reason for why the patch is needed or
4792 useful.
47884793
47894794 Your patch should include regression tests where possible, otherwise
47904795 it will be delayed until I get a chance to write them.
4796
4797 To browse Imager's git repository:
4798
4799 http://git.imager.perl.org/imager.git
4800
4801 or:
4802
4803 https://github.com/tonycoz/imager
4804
4805 To clone:
4806
4807 git clone git://git.imager.perl.org/imager.git
4808
4809 or:
4810
4811 git clone git://github.com/tonycoz/imager.git
47914812
47924813 =head1 AUTHOR
47934814
66 #include "XSUB.h"
77 #define NEED_newRV_noinc
88 #define NEED_sv_2pv_nolen
9 #define NEED_sv_2pvbyte
910 #include "ppport.h"
1011 #ifdef __cplusplus
1112 }
130131
131132 static void
132133 i_log_entry(char *string, int level) {
133 mm_log((level, string));
134 mm_log((level, "%s", string));
134135 }
135136
136137
142143 SV *readcb;
143144 SV *seekcb;
144145 SV *closecb;
145
146 /* we need to remember whether the buffer contains write data or
147 read data
148 */
149 int reading;
150 int writing;
151
152 /* how far we've read into the buffer (not used for writing) */
153 int where;
154
155 /* the amount of space used/data available in the buffer */
156 int used;
157
158 /* the maximum amount to fill the buffer before flushing
159 If any write is larger than this then the buffer is flushed and
160 the full write is performed. The write is _not_ split into
161 maxwrite sized calls
162 */
163 int maxlength;
164
165 char buffer[CBDATA_BUFSIZE];
166146 };
167147
168 /*
169
170 call_writer(cbd, buf, size)
171
172 Low-level function to call the perl writer callback.
173
174 */
175
176 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
177 dTHX;
178 int count;
179 int success;
180 SV *sv;
181 dSP;
182
183 if (!SvOK(cbd->writecb))
184 return -1;
185
186 ENTER;
187 SAVETMPS;
188 EXTEND(SP, 1);
189 PUSHMARK(SP);
190 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
191 PUTBACK;
192
193 count = perl_call_sv(cbd->writecb, G_SCALAR);
194
195 SPAGAIN;
196 if (count != 1)
197 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
198
199 sv = POPs;
200 success = SvTRUE(sv);
201
202
203 PUTBACK;
204 FREETMPS;
205 LEAVE;
206
207 return success ? size : -1;
208 }
209
210 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
211 size_t maxread) {
148 static ssize_t
149 call_reader(struct cbdata *cbd, void *buf, size_t size,
150 size_t maxread) {
212151 dTHX;
213152 int count;
214153 int result;
237176
238177 if (SvOK(data)) {
239178 STRLEN len;
240 char *ptr = SvPV(data, len);
179 char *ptr = SvPVbyte(data, len);
241180 if (len > maxread)
242 croak("Too much data returned in reader callback");
181 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
182 (int)size, (int)len, (int)maxread);
243183
244184 memcpy(buf, ptr, len);
245185 result = len;
255195 return result;
256196 }
257197
258 static ssize_t write_flush(struct cbdata *cbd) {
259 dTHX;
260 ssize_t result;
261
262 if (cbd->used) {
263 result = call_writer(cbd, cbd->buffer, cbd->used);
264 cbd->used = 0;
265 return result;
266 }
267 else {
268 return 1; /* success of some sort */
269 }
270 }
271
272 static off_t io_seeker(void *p, off_t offset, int whence) {
198 static off_t
199 io_seeker(void *p, off_t offset, int whence) {
273200 dTHX;
274201 struct cbdata *cbd = p;
275202 int count;
279206 if (!SvOK(cbd->seekcb))
280207 return -1;
281208
282 if (cbd->writing) {
283 if (cbd->used && write_flush(cbd) <= 0)
284 return -1;
285 cbd->writing = 0;
286 }
287 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
288 offset -= cbd->where - cbd->used;
289 }
290 cbd->reading = 0;
291 cbd->where = cbd->used = 0;
292
293209 ENTER;
294210 SAVETMPS;
295211 EXTEND(SP, 2);
314230 return result;
315231 }
316232
317 static ssize_t io_writer(void *p, void const *data, size_t size) {
233 static ssize_t
234 io_writer(void *p, void const *data, size_t size) {
318235 dTHX;
319236 struct cbdata *cbd = p;
320
321 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
322 if (!cbd->writing) {
323 if (cbd->reading && cbd->where < cbd->used) {
324 /* we read past the place where the caller expected us to be
325 so adjust our position a bit */
326 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
327 return -1;
328 }
329 cbd->reading = 0;
330 }
331 cbd->where = cbd->used = 0;
332 }
333 cbd->writing = 1;
334 if (cbd->used && cbd->used + size > cbd->maxlength) {
335 int write_res = write_flush(cbd);
336 if (write_res <= 0) {
337 return write_res;
338 }
339 cbd->used = 0;
340 }
341 if (cbd->used+size <= cbd->maxlength) {
342 memcpy(cbd->buffer + cbd->used, data, size);
343 cbd->used += size;
344 return size;
345 }
346 /* it doesn't fit - just pass it up */
347 return call_writer(cbd, data, size);
237 I32 count;
238 SV *sv;
239 dSP;
240 bool success;
241
242 if (!SvOK(cbd->writecb))
243 return -1;
244
245 ENTER;
246 SAVETMPS;
247 EXTEND(SP, 1);
248 PUSHMARK(SP);
249 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
250 PUTBACK;
251
252 count = perl_call_sv(cbd->writecb, G_SCALAR);
253
254 SPAGAIN;
255 if (count != 1)
256 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
257
258 sv = POPs;
259 success = SvTRUE(sv);
260
261
262 PUTBACK;
263 FREETMPS;
264 LEAVE;
265
266 return success ? size : -1;
348267 }
349268
350269 static ssize_t
351270 io_reader(void *p, void *data, size_t size) {
352 dTHX;
353271 struct cbdata *cbd = p;
354 ssize_t total;
355 char *out = data; /* so we can do pointer arithmetic */
356
357 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
358 if (cbd->writing) {
359 if (write_flush(cbd) <= 0)
360 return 0;
361 cbd->writing = 0;
362 }
363
364 cbd->reading = 1;
365 if (size <= cbd->used - cbd->where) {
366 /* simplest case */
367 memcpy(data, cbd->buffer+cbd->where, size);
368 cbd->where += size;
369 return size;
370 }
371 total = 0;
372 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
373 total += cbd->used - cbd->where;
374 size -= cbd->used - cbd->where;
375 out += cbd->used - cbd->where;
376 if (size < sizeof(cbd->buffer)) {
377 int did_read = 0;
378 int copy_size;
379 while (size
380 && (did_read = call_reader(cbd, cbd->buffer, size,
381 sizeof(cbd->buffer))) > 0) {
382 cbd->where = 0;
383 cbd->used = did_read;
384
385 copy_size = i_min(size, cbd->used);
386 memcpy(out, cbd->buffer, copy_size);
387 cbd->where += copy_size;
388 out += copy_size;
389 total += copy_size;
390 size -= copy_size;
391 }
392 if (did_read < 0)
393 return -1;
394 }
395 else {
396 /* just read the rest - too big for our buffer*/
397 int did_read;
398 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
399 size -= did_read;
400 total += did_read;
401 out += did_read;
402 }
403 if (did_read < 0)
404 return -1;
405 }
406
407 return total;
272
273 return call_reader(cbd, data, size, size);
408274 }
409275
410276 static int io_closer(void *p) {
411277 dTHX;
412278 struct cbdata *cbd = p;
413
414 if (cbd->writing && cbd->used > 0) {
415 if (write_flush(cbd) < 0)
416 return -1;
417 cbd->writing = 0;
418 }
279 int success = 1;
419280
420281 if (SvOK(cbd->closecb)) {
421282 dSP;
283 I32 count;
284 SV *sv;
422285
423286 ENTER;
424287 SAVETMPS;
425288 PUSHMARK(SP);
426289 PUTBACK;
427290
428 perl_call_sv(cbd->closecb, G_VOID);
291 count = perl_call_sv(cbd->closecb, G_SCALAR);
429292
430293 SPAGAIN;
294
295 sv = POPs;
296 success = SvTRUE(sv);
297
431298 PUTBACK;
432299 FREETMPS;
433300 LEAVE;
434301 }
435302
436 return 0;
303 return success ? 0 : -1;
437304 }
438305
439306 static void io_destroyer(void *p) {
445312 SvREFCNT_dec(cbd->seekcb);
446313 SvREFCNT_dec(cbd->closecb);
447314 myfree(cbd);
315 }
316
317 static i_io_glue_t *
318 do_io_new_buffer(pTHX_ SV *data_sv) {
319 const char *data;
320 STRLEN length;
321
322 data = SvPVbyte(data_sv, length);
323 SvREFCNT_inc(data_sv);
324 return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
325 }
326
327 static i_io_glue_t *
328 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
329 struct cbdata *cbd;
330
331 cbd = mymalloc(sizeof(struct cbdata));
332 cbd->writecb = newSVsv(writecb);
333 cbd->readcb = newSVsv(readcb);
334 cbd->seekcb = newSVsv(seekcb);
335 cbd->closecb = newSVsv(closecb);
336
337 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
338 io_destroyer);
448339 }
449340
450341 struct value_name {
896787
897788 #define i_img_epsilonf() (DBL_EPSILON * 4)
898789
790 /* avoid some xsubpp strangeness */
791 #define NEWLINE '\n'
792
899793 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
900794
901795 Imager::Color
1047941
1048942
1049943 Imager::IO
1050 io_new_buffer(data)
1051 char *data
1052 PREINIT:
1053 size_t length;
944 io_new_buffer(data_sv)
945 SV *data_sv
1054946 CODE:
1055 SvPV(ST(0), length);
1056 SvREFCNT_inc(ST(0));
1057 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
947 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1058948 OUTPUT:
1059949 RETVAL
1060950
1065955 SV *seekcb;
1066956 SV *closecb;
1067957 int maxwrite;
1068 PREINIT:
1069 struct cbdata *cbd;
1070958 CODE:
1071 cbd = mymalloc(sizeof(struct cbdata));
1072 SvREFCNT_inc(writecb);
1073 cbd->writecb = writecb;
1074 SvREFCNT_inc(readcb);
1075 cbd->readcb = readcb;
1076 SvREFCNT_inc(seekcb);
1077 cbd->seekcb = seekcb;
1078 SvREFCNT_inc(closecb);
1079 cbd->closecb = closecb;
1080 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1081 if (maxwrite > CBDATA_BUFSIZE)
1082 maxwrite = CBDATA_BUFSIZE;
1083 cbd->maxlength = maxwrite;
1084 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1085 io_destroyer);
959 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1086960 OUTPUT:
1087961 RETVAL
1088962
1089 void
963 SV *
1090964 io_slurp(ig)
1091965 Imager::IO ig
1092966 PREINIT:
1093967 unsigned char* data;
1094968 size_t tlength;
1095 PPCODE:
969 CODE:
1096970 data = NULL;
1097971 tlength = io_slurp(ig, &data);
1098 EXTEND(SP,1);
1099 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
972 RETVAL = newSVpv((char *)data,tlength);
1100973 myfree(data);
974 OUTPUT:
975 RETVAL
1101976
1102977
1103978 undef_int
1119994 PUSHs(sv_2mortal(newSVuv(bytes)));
1120995 }
1121996
997 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
998
999 Imager::IO
1000 io_new_fd(class, fd)
1001 int fd
1002 CODE:
1003 RETVAL = io_new_fd(fd);
1004 OUTPUT:
1005 RETVAL
1006
1007 Imager::IO
1008 io_new_buffer(class, data_sv)
1009 SV *data_sv
1010 CODE:
1011 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1012 OUTPUT:
1013 RETVAL
1014
1015 Imager::IO
1016 io_new_cb(class, writecb, readcb, seekcb, closecb)
1017 SV *writecb;
1018 SV *readcb;
1019 SV *seekcb;
1020 SV *closecb;
1021 CODE:
1022 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1023 OUTPUT:
1024 RETVAL
1025
1026 Imager::IO
1027 io_new_bufchain(class)
1028 CODE:
1029 RETVAL = io_new_bufchain();
1030 OUTPUT:
1031 RETVAL
1032
1033 SV *
1034 io_slurp(class, ig)
1035 Imager::IO ig
1036 PREINIT:
1037 unsigned char* data;
1038 size_t tlength;
1039 CODE:
1040 data = NULL;
1041 tlength = io_slurp(ig, &data);
1042 RETVAL = newSVpv((char *)data,tlength);
1043 myfree(data);
1044 OUTPUT:
1045 RETVAL
1046
11221047 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
11231048
1124 int
1125 i_io_write(ig, data_sv)
1049 IV
1050 i_io_raw_write(ig, data_sv)
11261051 Imager::IO ig
11271052 SV *data_sv
11281053 PREINIT:
11371062 }
11381063 #endif
11391064 data = SvPV(data_sv, size);
1140 RETVAL = i_io_write(ig, data, size);
1065 RETVAL = i_io_raw_write(ig, data, size);
11411066 OUTPUT:
11421067 RETVAL
1068
1069 void
1070 i_io_raw_read(ig, buffer_sv, size)
1071 Imager::IO ig
1072 SV *buffer_sv
1073 IV size
1074 PREINIT:
1075 void *buffer;
1076 ssize_t result;
1077 PPCODE:
1078 if (size <= 0)
1079 croak("size negative in call to i_io_raw_read()");
1080 /* prevent an undefined value warning if they supplied an
1081 undef buffer.
1082 Orginally conditional on !SvOK(), but this will prevent the
1083 downgrade from croaking */
1084 sv_setpvn(buffer_sv, "", 0);
1085 #ifdef SvUTF8
1086 if (SvUTF8(buffer_sv))
1087 sv_utf8_downgrade(buffer_sv, FALSE);
1088 #endif
1089 buffer = SvGROW(buffer_sv, size+1);
1090 result = i_io_raw_read(ig, buffer, size);
1091 if (result >= 0) {
1092 SvCUR_set(buffer_sv, result);
1093 *SvEND(buffer_sv) = '\0';
1094 SvPOK_only(buffer_sv);
1095 EXTEND(SP, 1);
1096 PUSHs(sv_2mortal(newSViv(result)));
1097 }
1098 ST(1) = buffer_sv;
1099 SvSETMAGIC(ST(1));
1100
1101 void
1102 i_io_raw_read2(ig, size)
1103 Imager::IO ig
1104 IV size
1105 PREINIT:
1106 SV *buffer_sv;
1107 void *buffer;
1108 ssize_t result;
1109 PPCODE:
1110 if (size <= 0)
1111 croak("size negative in call to i_io_read2()");
1112 buffer_sv = newSV(size);
1113 buffer = SvGROW(buffer_sv, size+1);
1114 result = i_io_raw_read(ig, buffer, size);
1115 if (result >= 0) {
1116 SvCUR_set(buffer_sv, result);
1117 *SvEND(buffer_sv) = '\0';
1118 SvPOK_only(buffer_sv);
1119 EXTEND(SP, 1);
1120 PUSHs(sv_2mortal(buffer_sv));
1121 }
1122 else {
1123 /* discard it */
1124 SvREFCNT_dec(buffer_sv);
1125 }
1126
1127 off_t
1128 i_io_raw_seek(ig, position, whence)
1129 Imager::IO ig
1130 off_t position
1131 int whence
1132
1133 int
1134 i_io_raw_close(ig)
1135 Imager::IO ig
1136
1137 void
1138 i_io_DESTROY(ig)
1139 Imager::IO ig
1140
1141 int
1142 i_io_CLONE_SKIP(...)
1143 CODE:
1144 (void)items; /* avoid unused warning for XS variable */
1145 RETVAL = 1;
1146 OUTPUT:
1147 RETVAL
1148
1149 int
1150 i_io_getc(ig)
1151 Imager::IO ig
1152
1153 int
1154 i_io_putc(ig, c)
1155 Imager::IO ig
1156 int c
1157
1158 int
1159 i_io_close(ig)
1160 Imager::IO ig
1161
1162 int
1163 i_io_flush(ig)
1164 Imager::IO ig
1165
1166 int
1167 i_io_peekc(ig)
1168 Imager::IO ig
1169
1170 int
1171 i_io_seek(ig, off, whence)
1172 Imager::IO ig
1173 off_t off
1174 int whence
1175
1176 void
1177 i_io_peekn(ig, size)
1178 Imager::IO ig
1179 STRLEN size
1180 PREINIT:
1181 SV *buffer_sv;
1182 void *buffer;
1183 ssize_t result;
1184 PPCODE:
1185 buffer_sv = newSV(size+1);
1186 buffer = SvGROW(buffer_sv, size+1);
1187 result = i_io_peekn(ig, buffer, size);
1188 if (result >= 0) {
1189 SvCUR_set(buffer_sv, result);
1190 *SvEND(buffer_sv) = '\0';
1191 SvPOK_only(buffer_sv);
1192 EXTEND(SP, 1);
1193 PUSHs(sv_2mortal(buffer_sv));
1194 }
1195 else {
1196 /* discard it */
1197 SvREFCNT_dec(buffer_sv);
1198 }
11431199
11441200 void
11451201 i_io_read(ig, buffer_sv, size)
11761232 void
11771233 i_io_read2(ig, size)
11781234 Imager::IO ig
1179 IV size
1235 STRLEN size
11801236 PREINIT:
11811237 SV *buffer_sv;
11821238 void *buffer;
11831239 ssize_t result;
11841240 PPCODE:
1185 if (size <= 0)
1186 croak("size negative in call to i_io_read2()");
1241 if (size == 0)
1242 croak("size zero in call to read2()");
11871243 buffer_sv = newSV(size);
11881244 buffer = SvGROW(buffer_sv, size+1);
11891245 result = i_io_read(ig, buffer, size);
1190 if (result >= 0) {
1246 if (result > 0) {
11911247 SvCUR_set(buffer_sv, result);
11921248 *SvEND(buffer_sv) = '\0';
11931249 SvPOK_only(buffer_sv);
11991255 SvREFCNT_dec(buffer_sv);
12001256 }
12011257
1202 off_t
1203 i_io_seek(ig, position, whence)
1258 void
1259 i_io_gets(ig, size = 8192, eol = NEWLINE)
12041260 Imager::IO ig
1205 off_t position
1206 int whence
1207
1208 int
1209 i_io_close(ig)
1261 STRLEN size
1262 int eol
1263 PREINIT:
1264 SV *buffer_sv;
1265 void *buffer;
1266 ssize_t result;
1267 PPCODE:
1268 if (size < 2)
1269 croak("size too small in call to gets()");
1270 buffer_sv = sv_2mortal(newSV(size+1));
1271 buffer = SvPVX(buffer_sv);
1272 result = i_io_gets(ig, buffer, size+1, eol);
1273 if (result > 0) {
1274 SvCUR_set(buffer_sv, result);
1275 *SvEND(buffer_sv) = '\0';
1276 SvPOK_only(buffer_sv);
1277 EXTEND(SP, 1);
1278 PUSHs(buffer_sv);
1279 }
1280
1281 IV
1282 i_io_write(ig, data_sv)
12101283 Imager::IO ig
1211
1212 void
1213 i_io_DESTROY(ig)
1214 Imager::IO ig
1215
1216 int
1217 i_io_CLONE_SKIP(...)
1218 CODE:
1219 (void)items; /* avoid unused warning for XS variable */
1220 RETVAL = 1;
1221 OUTPUT:
1284 SV *data_sv
1285 PREINIT:
1286 void *data;
1287 STRLEN size;
1288 CODE:
1289 #ifdef SvUTF8
1290 if (SvUTF8(data_sv)) {
1291 data_sv = sv_2mortal(newSVsv(data_sv));
1292 /* yes, we want this to croak() if the SV can't be downgraded */
1293 sv_utf8_downgrade(data_sv, FALSE);
1294 }
1295 #endif
1296 data = SvPV(data_sv, size);
1297 RETVAL = i_io_write(ig, data, size);
1298 OUTPUT:
12221299 RETVAL
1300
1301 void
1302 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1303 Imager::IO ig
1304 int flags
1305
1306 bool
1307 i_io_set_buffered(ig, flag = 1)
1308 Imager::IO ig
1309 int flag
1310
1311 bool
1312 i_io_is_buffered(ig)
1313 Imager::IO ig
1314
1315 bool
1316 i_io_eof(ig)
1317 Imager::IO ig
1318
1319 bool
1320 i_io_error(ig)
1321 Imager::IO ig
12231322
12241323 MODULE = Imager PACKAGE = Imager
12251324
21092208 if (GIMME_V == G_ARRAY) {
21102209 EXTEND(SP, count);
21112210 for (i = 0; i < count; ++i) {
2112 PUSHs(sv_2mortal(newSViv(work[i])));
2211 PUSHs(boolSV(work[i]));
21132212 }
21142213 }
21152214 else {
23112410 XSRETURN(col_cnt);
23122411
23132412
2314 Imager::ImgRaw
2413 void
23152414 i_transform(im,opx,opy,parm)
23162415 Imager::ImgRaw im
23172416 PREINIT:
23242423 AV* av;
23252424 SV* sv1;
23262425 int i;
2327 CODE:
2426 i_img *result;
2427 PPCODE:
23282428 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
23292429 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
23302430 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
23522452 sv1=(*(av_fetch(av,i,0)));
23532453 parm[i]=(double)SvNV(sv1);
23542454 }
2355 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2455 result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
23562456 myfree(parm);
23572457 myfree(opy);
23582458 myfree(opx);
2359 ST(0) = sv_newmortal();
2360 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2361 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2362
2363 Imager::ImgRaw
2459 if (result) {
2460 SV *result_sv = sv_newmortal();
2461 EXTEND(SP, 1);
2462 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2463 PUSHs(result_sv);
2464 }
2465
2466 void
23642467 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
23652468 SV *sv_width
23662469 SV *sv_height
23842487 SV *sv1;
23852488 IV tmp;
23862489 int i;
2387 CODE:
2490 i_img *result;
2491 PPCODE:
23882492
23892493 in_imgs_count = av_len(av_in_imgs)+1;
23902494 for (i = 0; i < in_imgs_count; ++i) {
24392543 c_regs = mymalloc(c_regs_count * sizeof(i_color));
24402544 /* I don't bother initializing the colou?r registers */
24412545
2442 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2546 result=i_transform2(width, height, channels, ops, ops_count,
24432547 n_regs, n_regs_count,
24442548 c_regs, c_regs_count, in_imgs, in_imgs_count);
24452549 if (in_imgs)
24462550 myfree(in_imgs);
24472551 myfree(n_regs);
24482552 myfree(c_regs);
2449 ST(0) = sv_newmortal();
2450 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2451 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2553 if (result) {
2554 SV *result_sv = sv_newmortal();
2555 EXTEND(SP, 1);
2556 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2557 PUSHs(result_sv);
2558 }
24522559
24532560
24542561 void
37793886
37803887 BOOT:
37813888 PERL_SET_GLOBAL_CALLBACKS;
3782 PERL_PL_SET_GLOBAL_CALLBACKS;
3889 PERL_PL_SET_GLOBAL_CALLBACKS;
33 use vars qw($VERSION @ISA);
44
55 BEGIN {
6 $VERSION = "0.81";
6 $VERSION = "0.82";
77
88 eval {
99 require XSLoader;
1919 Imager->register_reader
2020 (
2121 type=>'jpeg',
22 single =>
22 single =>
2323 sub {
2424 my ($im, $io, %hsh) = @_;
2525
3737 $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
3838
3939 # Imager required configure through use
40 my @Imager_req = ( Imager => "0.85" );
40 my @Imager_req = ( Imager => "0.86" );
4141 if ($MM_ver >= 6.46) {
4242 $opts{META_MERGE} =
4343 {
104104
105105 mm_log((1,"wiol_fill_input_buffer(cinfo %p)\n", cinfo));
106106
107 nbytes = src->data->readcb(src->data, src->buffer, JPGS);
107 nbytes = i_io_read(src->data, src->buffer, JPGS);
108108
109109 if (nbytes <= 0) { /* Insert a fake EOI marker */
110110 src->pub.next_input_byte = fake_eoi;
218218 */
219219
220220 mm_log((1,"wiol_empty_output_buffer(cinfo %p)\n", cinfo));
221 rc = dest->data->writecb(dest->data, dest->buffer, JPGS);
221 rc = i_io_write(dest->data, dest->buffer, JPGS);
222222
223223 if (rc != JPGS) { /* XXX: Should raise some jpeg error */
224224 myfree(dest->buffer);
237237 /* yes, this needs to flush the buffer */
238238 /* needs error handling */
239239
240 if (dest->data->writecb(dest->data, dest->buffer, nbytes) != nbytes) {
240 if (i_io_write(dest->data, dest->buffer, nbytes) != nbytes) {
241241 myfree(dest->buffer);
242242 ERREXIT(cinfo, JERR_FILE_WRITE);
243243 }
244
244
245245 if (dest != NULL) myfree(dest->buffer);
246246 }
247247
720720
721721 jpeg_destroy_compress(&cinfo);
722722
723 ig->closecb(ig);
723 if (i_io_close(ig))
724 return 0;
724725
725726 return(1);
726727 }
1010 $Imager::formats{"jpeg"}
1111 or plan skip_all => "no jpeg support";
1212
13 plan tests => 101;
13 plan tests => 103;
1414
1515 my $green=i_color_new(0,255,0,255);
1616 my $blue=i_color_new(0,0,255,255);
5454 # write failure test
5555 open FH, "< testout/t101.jpg" or die "Cannot open testout/t101.jpg: $!";
5656 binmode FH;
57 ok(!$imoo->write(fd=>fileno(FH), type=>'jpeg'), 'failure handling');
57 my $io = Imager::io_new_fd(fileno(FH));
58 $io->set_buffered(0);
59 ok(!$imoo->write(io => $io, type=>'jpeg'), 'failure handling');
5860 close FH;
5961 print "# ",$imoo->errstr,"\n";
6062
323325 }
324326 my $data;
325327 ok($im->write(data => \$data, type=>'jpeg', jpegquality => 100),
326 "write big file to ensure wiol_empty_output_buffer is called");
328 "write big file to ensure wiol_empty_output_buffer is called")
329 or print "# ", $im->errstr, "\n";
327330
328331 # code coverage - write failure path in wiol_empty_output_buffer
329332 ok(!$im->write(callback => sub { return },
431434
432435 is_image($rdprog, $norm, "prog vs norm should be the same image");
433436 }
437
438 { # check close failures are handled correctly
439 my $im = test_image();
440 my $fail_close = sub {
441 Imager::i_push_error(0, "synthetic close failure");
442 return 0;
443 };
444 ok(!$im->write(type => "jpeg", callback => sub { 1 },
445 closecb => $fail_close),
446 "check failing close fails");
447 like($im->errstr, qr/synthetic close failure/,
448 "check error message");
449 }
00 --- #YAML:1.0
11 name: Imager
2 version: 0.85
2 version: 0.86
33 abstract: Perl extension for Generating 24 bit Images
44 author:
55 - Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson
1010 build_requires:
1111 ExtUtils::MakeMaker: 0
1212 requires:
13 Test::More: 0.47
13 Scalar::Util: 1
14 Test::More: 0.47
1415 resources:
1516 bugtracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager
1617 homepage: http://imager.perl.org/
166166 bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
167167 imext.o scale.o rubthru.o render.o paste.o compose.o flip.o);
168168
169 my %opts=(
170 'NAME' => 'Imager',
171 'VERSION_FROM' => 'Imager.pm',
172 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
173 'DEFINE' => "$OSDEF $CFLAGS",
174 'INC' => "$lib_cflags $DFLAGS $F_INC",
175 'OBJECT' => join(' ', @objs, $F_OBJECT),
176 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
177 PM => gen_PM(),
178 PREREQ_PM => { 'Test::More' => 0.47 },
179 );
169 my %opts=
170 (
171 'NAME' => 'Imager',
172 'VERSION_FROM' => 'Imager.pm',
173 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
174 'DEFINE' => "$OSDEF $CFLAGS",
175 'INC' => "$lib_cflags $DFLAGS $F_INC",
176 'OBJECT' => join(' ', @objs, $F_OBJECT),
177 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
178 PM => gen_PM(),
179 PREREQ_PM =>
180 {
181 'Test::More' => 0.47,
182 'Scalar::Util' => 1.00,
183 },
184 );
180185
181186 if ($coverage) {
182187 if ($Config{gccversion}) {
183 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
184 #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
188 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
189 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
185190 }
186191 else {
187192 die "Don't know the coverage C flags for your compiler\n";
3737 $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
3838
3939 # Imager required configure through use
40 my @Imager_req = ( Imager => "0.85" );
40 my @Imager_req = ( Imager => "0.86" );
4141 if ($MM_ver >= 6.46) {
4242 $opts{META_MERGE} =
4343 {
33 use vars qw($VERSION @ISA);
44
55 BEGIN {
6 $VERSION = "0.81";
6 $VERSION = "0.82";
77
88 eval {
99 require XSLoader;
3333 static void
3434 wiol_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
3535 io_glue *ig = png_get_io_ptr(png_ptr);
36 int rc = ig->readcb(ig, data, length);
36 int rc = i_io_read(ig, data, length);
3737 if (rc != length) png_error(png_ptr, "Read overflow error on an iolayer source.");
3838 }
3939
4141 wiol_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
4242 int rc;
4343 io_glue *ig = png_get_io_ptr(png_ptr);
44 rc = ig->writecb(ig, data, length);
44 rc = i_io_write(ig, data, length);
4545 if (rc != length) png_error(png_ptr, "Write error on an iolayer source.");
4646 }
4747
176176
177177 png_destroy_write_struct(&png_ptr, &info_ptr);
178178
179 ig->closecb(ig);
179 if (i_io_close(ig))
180 return 0;
180181
181182 return(1);
182183 }
11 use strict;
22 use Imager qw(:all);
33 use Test::More;
4 use Imager::Test qw(test_image_raw);
4 use Imager::Test qw(test_image_raw test_image);
55
66 -d "testout" or mkdir "testout";
77
1010 $Imager::formats{"png"}
1111 or plan skip_all => "No png support";
1212
13 plan tests => 33;
13 plan tests => 35;
1414
1515 my $green = i_color_new(0, 255, 0, 255);
1616 my $blue = i_color_new(0, 0, 255, 255);
146146 'test write_multi() callback failure');
147147 }
148148
149 { # check close failures are handled correctly
150 my $im = test_image();
151 my $fail_close = sub {
152 Imager::i_push_error(0, "synthetic close failure");
153 return 0;
154 };
155 ok(!$im->write(type => "png", callback => sub { 1 },
156 closecb => $fail_close),
157 "check failing close fails");
158 like($im->errstr, qr/synthetic close failure/,
159 "check error message");
160 }
161
149162 {
150163 ok(grep($_ eq 'png', Imager->read_types), "check png in read types");
151164 ok(grep($_ eq 'png', Imager->write_types), "check png in write types");
440440 Roderick Schertler ( Roderick )
441441 Nathan Torkington ( gnat )
442442 Gabriel Vasseur
443 kmx
444 Nicolas Roggli
445 Justin Davis
446 Maurice Height
447 Krzysztof Wojtaś
448 David Cantrell
449 Eleneldil G. Arilou
450 Slaven Rezic
451 Richard Fairhurst
452 Nikita Dedik
443453
444454 (and just to play it safe) all those I forgot to mention.
181181 mm_log((1,"i_readsgi(ig %p, partial %d)\n", ig, partial));
182182 i_clear_error();
183183
184 if (ig->readcb(ig, headbuf, 512) != 512) {
184 if (i_io_read(ig, headbuf, 512) != 512) {
185185 i_push_error(errno, "SGI image: could not read header");
186186 return NULL;
187187 }
374374 for(y = 0; y < height; y++) {
375375 int x;
376376
377 if (ig->readcb(ig, databuf, width) != width) {
377 if (i_io_read(ig, databuf, width) != width) {
378378 i_push_error(0, "SGI image: cannot read image data");
379379 i_img_destroy(img);
380380 myfree(linebuf);
435435 length_tab = mymalloc(height*channels*sizeof(unsigned long));
436436
437437 /* Read offset table */
438 if (ig->readcb(ig, databuf, height * channels * 4) != height * channels * 4) {
438 if (i_io_read(ig, databuf, height * channels * 4) != height * channels * 4) {
439439 i_push_error(0, "SGI image: short read reading RLE start table");
440440 goto ErrorReturn;
441441 }
446446
447447
448448 /* Read length table */
449 if (ig->readcb(ig, databuf, height*channels*4) != height*channels*4) {
449 if (i_io_read(ig, databuf, height*channels*4) != height*channels*4) {
450450 i_push_error(0, "SGI image: short read reading RLE length table");
451451 goto ErrorReturn;
452452 }
519519 int pixels_left = width;
520520 i_sample_t sample;
521521
522 if (ig->seekcb(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) {
522 if (i_io_seek(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) {
523523 i_push_error(0, "SGI image: cannot seek to RLE data");
524524 goto ErrorReturn;
525525 }
526 if (ig->readcb(ig, databuf, datalen) != datalen) {
526 if (i_io_read(ig, databuf, datalen) != datalen) {
527527 i_push_error(0, "SGI image: cannot read RLE data");
528528 goto ErrorReturn;
529529 }
655655 for(y = 0; y < height; y++) {
656656 int x;
657657
658 if (ig->readcb(ig, databuf, width*2) != width*2) {
658 if (i_io_read(ig, databuf, width*2) != width*2) {
659659 i_push_error(0, "SGI image: cannot read image data");
660660 i_img_destroy(img);
661661 myfree(linebuf);
737737 i_push_error(0, "SGI image: invalid RLE length value for BPC=2");
738738 goto ErrorReturn;
739739 }
740 if (ig->seekcb(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) {
740 if (i_io_seek(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) {
741741 i_push_error(0, "SGI image: cannot seek to RLE data");
742742 goto ErrorReturn;
743743 }
744 if (ig->readcb(ig, databuf, datalen) != datalen) {
744 if (i_io_read(ig, databuf, datalen) != datalen) {
745745 i_push_error(0, "SGI image: cannot read RLE data");
746746 goto ErrorReturn;
747747 }
911911 for (c = 0; c < img->channels; ++c) {
912912 for (y = img->ysize - 1; y >= 0; --y) {
913913 i_gsamp(img, 0, width, y, linebuf, &c, 1);
914 if (ig->writecb(ig, linebuf, width) != width) {
914 if (i_io_write(ig, linebuf, width) != width) {
915915 i_push_error(errno, "SGI image: error writing image data");
916916 myfree(linebuf);
917917 return 0;
919919 }
920920 }
921921 myfree(linebuf);
922
923 if (i_io_close(ig))
924 return 0;
922925
923926 return 1;
924927 }
10101013 store_32(lengths + offset_pos, comp_size);
10111014 offset_pos += 4;
10121015 current_offset += comp_size;
1013 if (ig->writecb(ig, comp_buf, comp_size) != comp_size) {
1016 if (i_io_write(ig, comp_buf, comp_size) != comp_size) {
10141017 i_push_error(errno, "SGI image: error writing RLE data");
10151018 goto Error;
10161019 }
10311034 myfree(offsets);
10321035 myfree(comp_buf);
10331036 myfree(linebuf);
1037
1038 if (i_io_close(ig))
1039 return 0;
10341040
10351041 return 1;
10361042
10601066 unsigned short samp16 = SampleFTo16(linebuf[x]);
10611067 store_16(outp, samp16);
10621068 }
1063 if (ig->writecb(ig, encbuf, width * 2) != width * 2) {
1069 if (i_io_write(ig, encbuf, width * 2) != width * 2) {
10641070 i_push_error(errno, "SGI image: error writing image data");
10651071 myfree(linebuf);
10661072 myfree(encbuf);
10701076 }
10711077 myfree(linebuf);
10721078 myfree(encbuf);
1079
1080 if (i_io_close(ig))
1081 return 0;
10731082
10741083 return 1;
10751084 }
11701179 store_32(lengths + offset_pos, comp_size);
11711180 offset_pos += 4;
11721181 current_offset += comp_size;
1173 if (ig->writecb(ig, comp_buf, comp_size) != comp_size) {
1182 if (i_io_write(ig, comp_buf, comp_size) != comp_size) {
11741183 i_push_error(errno, "SGI image: error writing RLE data");
11751184 goto Error;
11761185 }
11921201 myfree(comp_buf);
11931202 myfree(linebuf);
11941203 myfree(sampbuf);
1204
1205 if (i_io_close(ig))
1206 return 0;
11951207
11961208 return 1;
11971209
00 #!perl -w
11 use strict;
22 use Imager;
3 use Test::More tests => 55;
3 use Test::More tests => 57;
44 use Imager::Test qw(test_image test_image_16 is_image);
55 use IO::Seekable;
66
160160 );
161161 for my $test (@tests) {
162162 my ($im, $limit, $expected_msg, $desc) = @$test;
163 my ($writecb, $seekcb) = limited_write($limit);
164 ok(!$im->write(type => 'sgi', writecb => $writecb,
165 seekcb => $seekcb, maxbuffer => 1),
163 my $io = limited_write_io($limit);
164 ok(!$im->write(type => 'sgi', io => $io),
166165 "write should fail - $desc");
167166 is($im->errstr, "$expected_msg: limit reached", "check error - $desc");
168167 }
168 }
169
170
171 { # check close failures are handled correctly
172 my $im = test_image();
173 my $fail_close = sub {
174 Imager::i_push_error(0, "synthetic close failure");
175 return 0;
176 };
177 ok(!$im->write(type => "sgi", callback => sub { 1 },
178 closecb => $fail_close),
179 "check failing close fails");
180 like($im->errstr, qr/synthetic close failure/,
181 "check error message");
182 }
183
184 sub limited_write_io {
185 my ($limit) = @_;
186
187 my ($writecb, $seekcb) = limited_write($limit);
188
189 my $io = Imager::io_new_cb($writecb, undef, $seekcb, undef, 1);
190 $io->set_buffered(0);
191
192 return $io;
169193 }
170194
171195 sub limited_write {
44 @ISA = qw(Imager::Font);
55
66 BEGIN {
7 $VERSION = "1.014";
7 $VERSION = "1.015";
88
99 eval {
1010 require XSLoader;
3434
3535 sub new {
3636 my $class = shift;
37 my %hsh=(color=>Imager::Color->new(255,0,0,0),
37 my %hsh=(color=>Imager::Color->new(255,0,0,255),
3838 size=>15,
3939 @_);
4040
7373
7474 my $id = i_t1_new($hsh{file},$hsh{afm});
7575 unless ($id >= 0) { # the low-level code may miss some error handling
76 $Imager::ERRSTR = "Could not load font ($id)";
76 Imager->_set_error(Imager->_error_as_msg);
7777 return;
7878 }
7979 return bless {
133133 if (GIMME_V == G_ARRAY) {
134134 EXTEND(SP, count);
135135 for (i = 0; i < count; ++i) {
136 PUSHs(sv_2mortal(newSViv(work[i])));
136 PUSHs(boolSV(work[i]));
137137 }
138138 }
139139 else {
9292 font_id = T1_AddFont(pfb);
9393 if (font_id<0) {
9494 mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id));
95 t1_push_error();
9596 return font_id;
9697 }
9798
100101 if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm));
101102 }
102103
104 if (T1_LoadFont(font_id)) {
105 mm_log((1, "i_t1_new() -> -1 - T1_LoadFont failed (%d)\n", T1_errno));
106 t1_push_error();
107 i_push_error(0, "loading font");
108 T1_DeleteFont(font_id);
109 return -1;
110 }
111
103112 ++t1_active_fonts;
113
114 mm_log((1, "i_t1_new() -> %d\n", font_id));
104115
105116 return font_id;
106117 }
571582
572583 static void
573584 t1_push_error(void) {
585 #if T1LIB_VERSION > 5 || T1LIB_VERSION == 5 && T1LIB_VERSION >= 1
586 /* I don't know when T1_StrError() was introduced, be conservative */
587 i_push_error(T1_errno, T1_StrError(T1_errno));
588 #else
574589 switch (T1_errno) {
575590 case 0:
576591 i_push_error(0, "No error");
681696 default:
682697 i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno);
683698 }
684 }
685
699 #endif
700 }
701
00 #!/usr/bin/perl -w
11 use strict;
22 use Imager;
3 use Test::More tests => 9;
3 use Imager::Test qw(isnt_image);
4 use Test::More tests => 14;
45
56 # extracted from t/t36oofont.t
67
5960 "write t36oofont1.ppm")
6061 or print "# ",$img->errstr,"\n";
6162
63 { # RT 71469
64 my $font1 = Imager::Font->new(file => $fontname_pfb, type => "t1");
65 my $font2 = Imager::Font::T1->new(file => $fontname_pfb);
66
67 for my $font ($font1, $font2) {
68 print "# ", join(",", $font->{color}->rgba), "\n";
69
70 my $im = Imager->new(xsize => 20, ysize => 20, channels => 4);
71
72 ok($im->string(text => "T", font => $font, y => 15),
73 "draw with default color")
74 or print "# ", $im->errstr, "\n";
75 my $work = Imager->new(xsize => 20, ysize => 20);
76 my $cmp = $work->copy;
77 $work->rubthrough(src => $im);
78 isnt_image($work, $cmp, "make sure something was drawn");
79 }
80 }
81
82 { # open a non-font as a font (test open failure)
83 local $ENV{LANG} = "C";
84 local $ENV{LC_ALL} = "C";
85 my $font = Imager::Font->new(file => "t/t20oo.t", type => "t1");
86 ok(!$font, "should fail to open test script as a font");
87 print "# ", Imager->errstr, "\n";
88 }
89
6290 unless ($ENV{IMAGER_KEEP_FILES}) {
6391 unlink "testout/t36oofont1.ppm";
6492 }
3737 $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
3838
3939 # Imager required configure through use
40 my @Imager_req = ( Imager => "0.85" );
40 my @Imager_req = ( Imager => "0.86" );
4141 if ($MM_ver >= 6.46) {
4242 $opts{META_MERGE} =
4343 {
33 use vars qw($VERSION @ISA);
44
55 BEGIN {
6 $VERSION = "0.81";
6 $VERSION = "0.82";
77
88 eval {
99 require XSLoader;
233233 toff_t
234234 comp_seek(thandle_t h, toff_t o, int w) {
235235 io_glue *ig = (io_glue*)h;
236 return (toff_t) ig->seekcb(ig, o, w);
236 return (toff_t) i_io_seek(ig, o, w);
237237 }
238238
239239 /*
265265 static void
266266 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
267267 /* do nothing */
268 }
269
270 static tsize_t
271 comp_read(thandle_t h, tdata_t p, tsize_t size) {
272 return i_io_read((io_glue *)h, p, size);
273 }
274
275 static tsize_t
276 comp_write(thandle_t h, tdata_t p, tsize_t size) {
277 return i_io_write((io_glue *)h, p, size);
278 }
279
280 static int
281 comp_close(thandle_t h) {
282 return i_io_close((io_glue *)h);
268283 }
269284
270285 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
546561 tif = TIFFClientOpen("(Iolayer)",
547562 "rm",
548563 (thandle_t) ig,
549 (TIFFReadWriteProc) ig->readcb,
550 (TIFFReadWriteProc) ig->writecb,
551 (TIFFSeekProc) comp_seek,
552 (TIFFCloseProc) ig->closecb,
553 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
554 (TIFFMapFileProc) comp_mmap,
555 (TIFFUnmapFileProc) comp_munmap);
564 comp_read,
565 comp_write,
566 comp_seek,
567 comp_close,
568 sizeproc,
569 comp_mmap,
570 comp_munmap);
556571
557572 if (!tif) {
558573 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
596611 TIFFErrorHandler old_warn_handler;
597612 i_img **results = NULL;
598613 int result_alloc = 0;
599 int dirnum = 0;
600614
601615 i_clear_error();
602616 old_handler = TIFFSetErrorHandler(error_handler);
612626 tif = TIFFClientOpen("(Iolayer)",
613627 "rm",
614628 (thandle_t) ig,
615 (TIFFReadWriteProc) ig->readcb,
616 (TIFFReadWriteProc) ig->writecb,
617 (TIFFSeekProc) comp_seek,
618 (TIFFCloseProc) ig->closecb,
619 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
620 (TIFFMapFileProc) comp_mmap,
621 (TIFFUnmapFileProc) comp_munmap);
629 comp_read,
630 comp_write,
631 comp_seek,
632 comp_close,
633 sizeproc,
634 comp_mmap,
635 comp_munmap);
622636
623637 if (!tif) {
624638 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
13291343 tif = TIFFClientOpen("No name",
13301344 "wm",
13311345 (thandle_t) ig,
1332 (TIFFReadWriteProc) ig->readcb,
1333 (TIFFReadWriteProc) ig->writecb,
1334 (TIFFSeekProc) comp_seek,
1335 (TIFFCloseProc) ig->closecb,
1336 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1337 (TIFFMapFileProc) comp_mmap,
1338 (TIFFUnmapFileProc) comp_munmap);
1346 comp_read,
1347 comp_write,
1348 comp_seek,
1349 comp_close,
1350 sizeproc,
1351 comp_mmap,
1352 comp_munmap);
13391353
13401354
13411355
13641378 TIFFSetErrorHandler(old_handler);
13651379 (void) TIFFClose(tif);
13661380
1381 if (i_io_close(ig))
1382 return 0;
1383
13671384 return 1;
13681385 }
13691386
13971414 tif = TIFFClientOpen("No name",
13981415 "wm",
13991416 (thandle_t) ig,
1400 (TIFFReadWriteProc) ig->readcb,
1401 (TIFFReadWriteProc) ig->writecb,
1402 (TIFFSeekProc) comp_seek,
1403 (TIFFCloseProc) ig->closecb,
1404 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1405 (TIFFMapFileProc) comp_mmap,
1406 (TIFFUnmapFileProc) comp_munmap);
1417 comp_read,
1418 comp_write,
1419 comp_seek,
1420 comp_close,
1421 sizeproc,
1422 comp_mmap,
1423 comp_munmap);
14071424
14081425
14091426
14311448
14321449 (void) TIFFClose(tif);
14331450 TIFFSetErrorHandler(old_handler);
1451
1452 if (i_io_close(ig))
1453 return 0;
14341454
14351455 return 1;
14361456 }
14601480 tif = TIFFClientOpen("No name",
14611481 "wm",
14621482 (thandle_t) ig,
1463 (TIFFReadWriteProc) ig->readcb,
1464 (TIFFReadWriteProc) ig->writecb,
1465 (TIFFSeekProc) comp_seek,
1466 (TIFFCloseProc) ig->closecb,
1467 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1468 (TIFFMapFileProc) comp_mmap,
1469 (TIFFUnmapFileProc) comp_munmap);
1483 comp_read,
1484 comp_write,
1485 comp_seek,
1486 comp_close,
1487 sizeproc,
1488 comp_mmap,
1489 comp_munmap);
14701490
14711491
14721492
14861506 (void) TIFFClose(tif);
14871507 TIFFSetErrorHandler(old_handler);
14881508
1509 if (i_io_close(ig))
1510 return 0;
1511
14891512 return 1;
14901513 }
14911514
15211544 tif = TIFFClientOpen("No name",
15221545 "wm",
15231546 (thandle_t) ig,
1524 (TIFFReadWriteProc) ig->readcb,
1525 (TIFFReadWriteProc) ig->writecb,
1526 (TIFFSeekProc) comp_seek,
1527 (TIFFCloseProc) ig->closecb,
1528 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1529 (TIFFMapFileProc) comp_mmap,
1530 (TIFFUnmapFileProc) comp_munmap);
1547 comp_read,
1548 comp_write,
1549 comp_seek,
1550 comp_close,
1551 sizeproc,
1552 comp_mmap,
1553 comp_munmap);
15311554
15321555
15331556
15461569
15471570 (void) TIFFClose(tif);
15481571 TIFFSetErrorHandler(old_handler);
1572
1573 if (i_io_close(ig))
1574 return 0;
15491575
15501576 return 1;
15511577 }
00 #!perl -w
11 use strict;
2 use Test::More tests => 235;
2 use Test::More tests => 239;
33 use Imager qw(:all);
44 use Imager::Test qw(is_image is_image_similar test_image test_image_16 test_image_double test_image_raw);
55
203203 }
204204 sub io_reader {
205205 my ($size, $maxread) = @_;
206 #print "io_reader($size, $maxread) pos $seekpos\n";
206 print "# io_reader($size, $maxread) pos $seekpos\n";
207 if ($seekpos + $maxread > length $work) {
208 $maxread = length($work) - $seekpos;
209 }
207210 my $out = substr($work, $seekpos, $maxread);
208211 $seekpos += length $out;
209212 $out;
210213 }
211214 sub io_reader2 {
212215 my ($size, $maxread) = @_;
213 #print "io_reader2($size, $maxread) pos $seekpos\n";
216 print "# io_reader2($size, $maxread) pos $seekpos\n";
214217 my $out = substr($work, $seekpos, $size);
215218 $seekpos += length $out;
216219 $out;
218221 use IO::Seekable;
219222 sub io_seeker {
220223 my ($offset, $whence) = @_;
221 #print "io_seeker($offset, $whence)\n";
224 print "# io_seeker($offset, $whence)\n";
222225 if ($whence == SEEK_SET) {
223226 $seekpos = $offset;
224227 }
285288 print D3 $work;
286289 close D3;
287290
291
292 { # check close failures are handled correctly
293 { # single image
294 my $im = test_image();
295 my $fail_close = sub {
296 Imager::i_push_error(0, "synthetic close failure");
297 return 0;
298 };
299 $work = '';
300 $seekpos = 0;
301 ok(!$im->write(type => "tiff",
302 readcb => \&io_reader,
303 writecb => \&io_writer,
304 seekcb => \&io_seeker,
305 closecb => $fail_close),
306 "check failing close fails");
307 like($im->errstr, qr/synthetic close failure/,
308 "check error message");
309 }
310 { # multiple images
311 my $im = test_image();
312 my $fail_close = sub {
313 Imager::i_push_error(0, "synthetic close failure");
314 return 0;
315 };
316 $work = '';
317 $seekpos = 0;
318 ok(!Imager->write_multi({type => "tiff",
319 readcb => \&io_reader,
320 writecb => \&io_writer,
321 seekcb => \&io_seeker,
322 closecb => $fail_close}, $im, $im),
323 "check failing close fails");
324 like(Imager->errstr, qr/synthetic close failure/,
325 "check error message");
326 }
327 }
328
288329 # multi-image write/read
289330 my @imgs;
290331 push(@imgs, map $ooim->copy(), 1..3);
380421 or skip "Cannot open testout/t106_empty.tif for reading", 8;
381422 binmode TIFF;
382423 my $im = Imager->new(xsize=>100, ysize=>100);
383 ok(!$im->write(fh => \*TIFF, type=>'tiff'),
424 ok(!$im->write(fh => \*TIFF, type=>'tiff', buffered => 0),
384425 "fail to write to read only handle");
385426 cmp_ok($im->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
386427 "check error message");
387 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF }, $im),
428 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF, buffered => 0 }, $im),
388429 "fail to write multi to read only handle");
389430 cmp_ok(Imager->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
390431 "check error message");
391 ok(!$im->write(fh => \*TIFF, type=>'tiff', class=>'fax'),
432 ok(!$im->write(fh => \*TIFF, type=>'tiff', class=>'fax', buffered => 0),
392433 "fail to write to read only handle (fax)");
393434 cmp_ok($im->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
394435 "check error message");
395 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF, class=>'fax' }, $im),
436 ok(!Imager->write_multi({ type => 'tiff', fh => \*TIFF, class=>'fax', buffered => 0 }, $im),
396437 "fail to write multi to read only handle (fax)");
397438 cmp_ok(Imager->errstr, '=~', 'Could not create TIFF object: Error writing TIFF header: write\(\)',
398439 "check error message");
Binary diff not shown
44 @ISA = qw(Imager::Font);
55
66 BEGIN {
7 $VERSION = "0.81";
7 $VERSION = "0.82";
88
99 eval {
1010 require XSLoader;
2121 # since Win32's HFONTs include the size information this
2222 # is just a stub
2323 sub new {
24 my ($class, %opts) = @_;
24 my $class = shift;
25 my %opts =
26 (
27 color => Imager::Color->new(255, 0, 0),
28 size => 15,
29 @_,
30 );
2531
2632 return bless \%opts, $class;
2733 }
00 #!perl -w
11 use strict;
2 use Test::More tests => 55;
2 use Test::More tests => 59;
33 use Imager qw(:all);
4 use Imager::Test qw(diff_text_with_nul);
4 use Imager::Test qw(diff_text_with_nul isnt_image);
55 ++$|;
66
77 ok(-d "testout" or mkdir("testout"), "testout directory");
2828 "i_wf_cp smoke test");
2929 i_line($overlay,0,50,100,50,$bgcolor, 1);
3030
31 open(FH,">testout/t10font.ppm") || die "cannot open testout/t10font.ppm\n";
32 binmode(FH);
33 my $io = Imager::io_new_fd(fileno(FH));
34 i_writeppm_wiol($overlay,$io);
35 close(FH);
31 if (open(FH,">testout/t10font.ppm")) {
32 binmode(FH);
33 my $io = Imager::io_new_fd(fileno(FH));
34 i_writeppm_wiol($overlay,$io);
35 close(FH);
36 }
37 else {
38 diag "cannot open testout/t10font.ppm: $!";
39 }
3640
3741 $bgcolor=i_color_set($bgcolor,200,200,200,0);
3842 my $backgr=Imager::ImgRaw::new(500,300,3);
4145 "i_wf_text smoke test");
4246 i_line($backgr,0, 100, 499, 100, NC(0, 0, 255), 1);
4347
44 open(FH,">testout/t10font2.ppm") || die "cannot open testout/t10font2.ppm\n";
45 binmode(FH);
46 $io = Imager::io_new_fd(fileno(FH));
47 i_writeppm_wiol($backgr,$io);
48 close(FH);
49
48 if (open(FH,">testout/t10font2.ppm")) {
49 binmode(FH);
50 my $io = Imager::io_new_fd(fileno(FH));
51 i_writeppm_wiol($backgr,$io);
52 close(FH);
53 }
54 else {
55 diag "cannot open testout/t10font2.ppm: $!";
56 }
57
5058 my $img = Imager->new(xsize=>200, ysize=>200);
5159 my $font = Imager::Font->new(face=>$fontname, size=>20);
5260 ok($img->string('x'=>30, 'y'=>30, string=>"Imager", color=>NC(255, 0, 0),
5361 font=>$font),
5462 "string with win32 smoke test")
55 or print "# ",$img->errstr,"\n";
56 $img->write(file=>'testout/t10_oo.ppm') or print "not ";
63 or diag "simple string output: ",$img->errstr;
64 $img->write(file=>'testout/t10_oo.ppm')
65 or diag "Cannot save t10_oo.ppm: ", $img->errstr;
5766 my @bbox2 = $font->bounding_box(string=>'Imager');
5867 is(@bbox2, 8, "got 8 values from bounding_box");
5968
6978 SKIP:
7079 {
7180 $^O eq 'cygwin' and skip("Too hard to get correct directory for test font on cygwin", 13);
72 ok(Imager::Font::W32::i_wf_addfont("fontfiles/ExistenceTest.ttf"), "add test font")
73 or print "# ",Imager::_error_as_msg(),"\n";
81 my $extra_font = "fontfiles/ExistenceTest.ttf";
82 unless (ok(Imager::Font::W32::i_wf_addfont($extra_font), "add test font")) {
83 diag "adding font resource: ",Imager::_error_as_msg();
84 skip("Could not add font resource", 12);
85 }
7486
7587 my $namefont = Imager::Font->new(face=>"ExistenceTest");
7688 ok($namefont, "create font based on added font");
8193 is(@bbox, 8, "should be 8 entries");
8294 isnt($bbox[6], $bbox[2], "different advance width");
8395 $bbox = $namefont->bounding_box(string=>"/", size=>100);
84 ok($bbox->pos_width != $bbox->advance_width, "OO check");
96 isnt($bbox->pos_width, $bbox->advance_width, "OO check");
8597
8698 cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
8799
99111 $im->line(color=>'blue', x1=>0, y1 => 100, x2=>199, y2 => 100);
100112 ok($im->string(font=>$namefont, text=>"/", x=>20, y=>100, color=>'white', size=>100),
101113 "draw / from ExistenceText")
102 or print "# ", $im->errstr, "\n";
114 or diag "draw / from ExistenceTest:", $im->errstr;
103115 $im->setpixel(x => 20+$bbox->neg_width, y => 100-$bbox->ascent, color => 'red');
104116 $im->setpixel(x => 20+$bbox->advance_width - $bbox->right_bearing, y => 100-$bbox->descent, color => 'red');
105117 $im->write(file=>'testout/t10_slash.ppm');
126138 $im->line(color=>'blue', x1=>0, y1 => 100, x2=>199, y2 => 100);
127139 ok($im->string(font=>$namefont, text=>"!", x=>20, y=>100, color=>'white', size=>100),
128140 "draw / from ExistenceText")
129 or print "# ", $im->errstr, "\n";
141 or diag "draw / from ExistenceTest: ", $im->errstr;
130142 $im->setpixel(x => 20+$bbox->neg_width, y => 100-$bbox->ascent, color => 'red');
131143 $im->setpixel(x => 20+$bbox->advance_width - $bbox->right_bearing, y => 100-$bbox->descent, color => 'red');
132144 $im->write(file=>'testout/t10_bang.ppm');
166178 ok($im->string(string => "\xE2\x98\xBA", size => 80, aa => 1, utf8 => 1,
167179 color => "white", font => $font, x => 5, y => 80),
168180 "draw in utf8 (hand encoded)")
169 or print "# ", $im->errstr, "\n";
170 ok($im->write(file=>'testout/t10utf8.ppm'), "save utf8 image");
181 or diag "draw utf8 hand-encoded ", $im->errstr;
182 ok($im->write(file=>'testout/t10utf8.ppm'), "save utf8 image")
183 or diag "save t10utf8.ppm: ", $im->errstr;
171184
172185 # native perl utf8
173186 # Win32 only supported on 5.6+
179192 ok($im2->string(string => $text, size => 80, aa => 1,
180193 color => 'white', font => $font, x => 5, y => 80),
181194 "draw in utf8 (perl utf8)")
182 or print "# ", $im->errstr, "\n";
195 or diag "draw in utf8: ", $im->errstr;
183196 ok($im2->write(file=>'testout/t10utf8b.ppm'), "save utf8 image");
184197 is(Imager::i_img_diff($im->{IMG}, $im2->{IMG}), 0,
185198 "check result is the same");
206219 diff_text_with_nul("utf8 dash\0dash vs dash - channel", "$dash\0$dash", $dash,
207220 font => $font, channel => 1, utf8 => 1);
208221 }
222
223 { # RT 71469
224 my $font1 = Imager::Font->new(face => $fontname, type => "w32");
225 my $font2 = Imager::Font::W32->new(face => $fontname );
226
227 for my $font ($font1, $font2) {
228 print "# ", join(",", $font->{color}->rgba), "\n";
229
230 my $im = Imager->new(xsize => 20, ysize => 20, channels => 4);
231
232 ok($im->string(text => "T", font => $font, y => 15),
233 "draw with default color")
234 or diag "draw with default color: ", $im->errstr;
235 my $work = Imager->new(xsize => 20, ysize => 20);
236 my $cmp = $work->copy;
237 $work->rubthrough(src => $im);
238 isnt_image($work, $cmp, "make sure something was drawn");
239 }
240 }
209241 }
321321 i_wf_addfont(char const *filename) {
322322 i_clear_error();
323323
324 mm_log((1, "i_wf_addfont(%s)\n", filename));
324325 if (!gdi_dll) {
325326 gdi_dll = GetModuleHandle("GDI32");
326327 if (gdi_dll) {
327328 AddFontResourceExAp = (AddFontResourceExA_t)GetProcAddress(gdi_dll, "AddFontResourceExA");
328329 RemoveFontResourceExAp = (RemoveFontResourceExA_t)GetProcAddress(gdi_dll, "RemoveFontResourceExA");
329 }
330 }
331
332 if (AddFontResourceExAp && RemoveFontResourceExAp
333 && AddFontResourceExAp(filename, FR_PRIVATE, 0)) {
334 return 1;
335 }
336 else if (AddFontResource(filename)) {
337 return 1;
338 }
339 else {
340 i_push_errorf(0, "Could not add resource: %ld", GetLastError());
341 return 0;
342 }
330 mm_log((1, "i_wf_addfont: AddFontResourceExA %p RemoveFontResourceExA %p\n",
331 AddFontResourceExAp, RemoveFontResourceExAp));
332 }
333 }
334
335 if (AddFontResourceExAp && RemoveFontResourceExAp) {
336 mm_log((1, "i_wf_addfont: adding via AddFontResourceEx()\n"));
337 if (AddFontResourceExAp(filename, FR_PRIVATE, 0)) {
338 return 1;
339 }
340 }
341 else {
342 mm_log((1, "i_wf_addfont: adding via AddFontResource()\n"));
343 if (AddFontResource(filename)) {
344 return 1;
345 }
346 }
347
348 mm_log((1, "i_wf_addfont failed: %ld\n", GetLastError()));
349 i_push_errorf(0, "Could not add resource: %ld", GetLastError());
350 return 0;
343351 }
344352
345353 /*
353361 i_wf_delfont(char const *filename) {
354362 i_clear_error();
355363
356 if (AddFontResourceExAp && RemoveFontResourceExAp
357 && RemoveFontResourceExAp(filename, FR_PRIVATE, 0)) {
358 return 1;
359 }
360 else if (RemoveFontResource(filename)) {
361 return 1;
362 }
363 else {
364 i_push_errorf(0, "Could not remove resource: %ld", GetLastError());
365 return 0;
366 }
364 mm_log((1, "i_wf_delfont(%s)\n", filename));
365
366 if (AddFontResourceExAp && RemoveFontResourceExAp) {
367 mm_log((1, "i_wf_delfont: removing via RemoveFontResourceEx()\n"));
368 if (RemoveFontResourceExAp(filename, FR_PRIVATE, 0))
369 return 1;
370 }
371 else {
372 mm_log((1, "i_wf_delfont: adding via RemoveFontResourceEx()\n"));
373 if (RemoveFontResource(filename))
374 return 1;
375 }
376
377 mm_log((1, "i_wf_delfont failed: %ld\n", GetLastError()));
378 i_push_errorf(0, "Could not remove resource: %ld", GetLastError());
379 return 0;
367380 }
368381
369382 /*
99 # look for files to parse
1010
1111 my $mani = maniread;
12 my @files = grep /\.(c|im|h)$/, keys %$mani;
12 my @files = sort grep /\.(c|im|h)$/, keys %$mani;
1313
1414 # scan each file for =item <func>\b
1515 my $func;
106106
107107 for my $cat (sort { lc $a cmp lc $b } keys %cats) {
108108 print OUT "\n # $cat\n";
109 for my $func (grep $funcsyns{$_}, sort { $order{$a} <=> $order{$b} } @{$cats{$cat}}) {
109 my @funcs = @{$cats{$cat}};
110 my %orig;
111 @orig{@funcs} = 0 .. $#funcs;
112 @funcs = sort { $order{$a} <=> $order{$b} || $orig{$a} <=> $orig{$b} } @funcs;
113 for my $func (grep $funcsyns{$_}, @funcs) {
110114 my $syn = $funcsyns{$func};
111115 $syn =~ s/^/ /gm;
112116 print OUT $syn;
188192 my $in_struct;
189193 while (<FUNCS>) {
190194 /^typedef struct/ && ++$in_struct;
191 if ($in_struct && /\(\*f_(i_\w+)/) {
192 push @funcs, $1;
195 if ($in_struct && /\(\*f_(io?_\w+)/) {
196 my $name = $1;
197 $name =~ s/_imp$//;
198 push @funcs, $name;
193199 }
194200 if (/^\} im_ext_funcs;$/) {
195201 $in_struct
+35
-33
bmp.c less more
7575 */
7676 int
7777 i_writebmp_wiol(i_img *im, io_glue *ig) {
78 io_glue_commit_types(ig);
7978 i_clear_error();
8079
8180 /* pick a format */
119118
120119 mm_log((1, "i_readbmp_wiol(ig %p)\n", ig));
121120
122 io_glue_commit_types(ig);
123121 i_clear_error();
124122
125123 if (!read_packed(ig, "CCVvvVVV!V!vvVVVVVV", &b_magic, &m_magic, &filesize,
236234
237235 switch (code) {
238236 case 'v':
239 if (ig->readcb(ig, buf, 2) != 2)
237 if (i_io_read(ig, buf, 2) != 2)
240238 return 0;
241239 work = buf[0] + ((i_packed_t)buf[1] << 8);
242240 if (shrieking)
246244 break;
247245
248246 case 'V':
249 if (ig->readcb(ig, buf, 4) != 4)
247 if (i_io_read(ig, buf, 4) != 4)
250248 return 0;
251249 work = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16) + ((i_packed_t)buf[3] << 24);
252250 if (shrieking)
256254 break;
257255
258256 case 'C':
259 if (ig->readcb(ig, buf, 1) != 1)
257 if (i_io_read(ig, buf, 1) != 1)
260258 return 0;
261259 *p = buf[0];
262260 break;
263261
264262 case 'c':
265 if (ig->readcb(ig, buf, 1) != 1)
263 if (i_io_read(ig, buf, 1) != 1)
266264 return 0;
267265 *p = (char)buf[0];
268266 break;
269267
270268 case '3': /* extension - 24-bit number */
271 if (ig->readcb(ig, buf, 3) != 3)
269 if (i_io_read(ig, buf, 3) != 3)
272270 return 0;
273271 *p = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16);
274272 break;
305303 case 'v':
306304 buf[0] = i & 255;
307305 buf[1] = i / 256;
308 if (ig->writecb(ig, buf, 2) == -1)
306 if (i_io_write(ig, buf, 2) == -1)
309307 return 0;
310308 break;
311309
314312 buf[1] = (i >> 8) & 0xFF;
315313 buf[2] = (i >> 16) & 0xFF;
316314 buf[3] = (i >> 24) & 0xFF;
317 if (ig->writecb(ig, buf, 4) == -1)
315 if (i_io_write(ig, buf, 4) == -1)
318316 return 0;
319317 break;
320318
321319 case 'C':
322320 case 'c':
323321 buf[0] = i & 0xFF;
324 if (ig->writecb(ig, buf, 1) == -1)
322 if (i_io_write(ig, buf, 1) == -1)
325323 return 0;
326324 break;
327325
490488 if (mask != 0x80) {
491489 *out++ = byte;
492490 }
493 if (ig->writecb(ig, packed, line_size) < 0) {
491 if (i_io_write(ig, packed, line_size) < 0) {
494492 myfree(packed);
495493 myfree(line);
496494 i_push_error(0, "writing 1 bit/pixel packed data");
500498 myfree(packed);
501499 myfree(line);
502500
503 ig->closecb(ig);
501 if (i_io_close(ig))
502 return 0;
504503
505504 return 1;
506505 }
549548 for (x = 0; x < im->xsize; x += 2) {
550549 *out++ = (line[x] << 4) + line[x+1];
551550 }
552 if (ig->writecb(ig, packed, line_size) < 0) {
551 if (i_io_write(ig, packed, line_size) < 0) {
553552 myfree(packed);
554553 myfree(line);
555554 i_push_error(0, "writing 4 bit/pixel packed data");
559558 myfree(packed);
560559 myfree(line);
561560
562 ig->closecb(ig);
561 if (i_io_close(ig))
562 return 0;
563563
564564 return 1;
565565 }
597597
598598 for (y = im->ysize-1; y >= 0; --y) {
599599 i_gpal(im, 0, im->xsize, y, line);
600 if (ig->writecb(ig, line, line_size) < 0) {
600 if (i_io_write(ig, line, line_size) < 0) {
601601 myfree(line);
602602 i_push_error(0, "writing 8 bit/pixel packed data");
603603 return 0;
605605 }
606606 myfree(line);
607607
608 ig->closecb(ig);
608 if (i_io_close(ig))
609 return 0;
609610
610611 return 1;
611612 }
651652 samplep[0] = tmp;
652653 samplep += 3;
653654 }
654 if (ig->writecb(ig, samples, line_size) < 0) {
655 if (i_io_write(ig, samples, line_size) < 0) {
655656 i_push_error(0, "writing image data");
656657 myfree(samples);
657658 return 0;
659660 }
660661 myfree(samples);
661662
662 ig->closecb(ig);
663 if (i_io_close(ig))
664 return 0;
663665
664666 return 1;
665667 }
772774 rare */
773775 char buffer;
774776 while (base_offset < offbits) {
775 if (ig->readcb(ig, &buffer, 1) != 1) {
777 if (i_io_read(ig, &buffer, 1) != 1) {
776778 i_img_destroy(im);
777779 i_push_error(0, "failed skipping to image data offset");
778780 return NULL;
786788 packed = mymalloc(line_size); /* checked 29jun05 tonyc */
787789 line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
788790 while (y != lasty) {
789 if (ig->readcb(ig, packed, line_size) != line_size) {
791 if (i_io_read(ig, packed, line_size) != line_size) {
790792 myfree(packed);
791793 myfree(line);
792794 if (allow_incomplete) {
889891 rare */
890892 char buffer;
891893 while (base_offset < offbits) {
892 if (ig->readcb(ig, &buffer, 1) != 1) {
894 if (i_io_read(ig, &buffer, 1) != 1) {
893895 i_img_destroy(im);
894896 i_push_error(0, "failed skipping to image data offset");
895897 return NULL;
907909 if (compression == BI_RGB) {
908910 i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
909911 while (y != lasty) {
910 if (ig->readcb(ig, packed, line_size) != line_size) {
912 if (i_io_read(ig, packed, line_size) != line_size) {
911913 myfree(packed);
912914 myfree(line);
913915 if (allow_incomplete) {
942944 x = 0;
943945 while (1) {
944946 /* there's always at least 2 bytes in a sequence */
945 if (ig->readcb(ig, packed, 2) != 2) {
947 if (i_io_read(ig, packed, 2) != 2) {
946948 myfree(packed);
947949 myfree(line);
948950 if (allow_incomplete) {
987989 return im;
988990
989991 case BMPRLE_DELTA:
990 if (ig->readcb(ig, packed, 2) != 2) {
992 if (i_io_read(ig, packed, 2) != 2) {
991993 myfree(packed);
992994 myfree(line);
993995 if (allow_incomplete) {
10171019 }
10181020 size = (count + 1) / 2;
10191021 read_size = (size+1) / 2 * 2;
1020 if (ig->readcb(ig, packed, read_size) != read_size) {
1022 if (i_io_read(ig, packed, read_size) != read_size) {
10211023 myfree(packed);
10221024 myfree(line);
10231025 if (allow_incomplete) {
11161118 rare */
11171119 char buffer;
11181120 while (base_offset < offbits) {
1119 if (ig->readcb(ig, &buffer, 1) != 1) {
1121 if (i_io_read(ig, &buffer, 1) != 1) {
11201122 i_img_destroy(im);
11211123 i_push_error(0, "failed skipping to image data offset");
11221124 return NULL;
11291131 if (compression == BI_RGB) {
11301132 i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
11311133 while (y != lasty) {
1132 if (ig->readcb(ig, line, line_size) != line_size) {
1134 if (i_io_read(ig, line, line_size) != line_size) {
11331135 myfree(line);
11341136 if (allow_incomplete) {
11351137 i_tags_setn(&im->tags, "i_incomplete", 1);
11561158 x = 0;
11571159 while (1) {
11581160 /* there's always at least 2 bytes in a sequence */
1159 if (ig->readcb(ig, packed, 2) != 2) {
1161 if (i_io_read(ig, packed, 2) != 2) {
11601162 myfree(line);
11611163 if (allow_incomplete) {
11621164 i_tags_setn(&im->tags, "i_incomplete", 1);
11921194 return im;
11931195
11941196 case BMPRLE_DELTA:
1195 if (ig->readcb(ig, packed, 2) != 2) {
1197 if (i_io_read(ig, packed, 2) != 2) {
11961198 myfree(line);
11971199 if (allow_incomplete) {
11981200 i_tags_setn(&im->tags, "i_incomplete", 1);
12201222 return NULL;
12211223 }
12221224 read_size = (count+1) / 2 * 2;
1223 if (ig->readcb(ig, line, read_size) != read_size) {
1225 if (i_io_read(ig, line, read_size) != read_size) {
12241226 myfree(line);
12251227 if (allow_incomplete) {
12261228 i_tags_setn(&im->tags, "i_incomplete", 1);
13231325 /* there's a potential "palette" after the header */
13241326 for (i = 0; i < clr_used; ++clr_used) {
13251327 char buf[4];
1326 if (ig->readcb(ig, buf, 4) != 4) {
1328 if (i_io_read(ig, buf, 4) != 4) {
13271329 i_push_error(0, "skipping colors");
13281330 return 0;
13291331 }
13671369 rare */
13681370 char buffer;
13691371 while (base_offset < offbits) {
1370 if (ig->readcb(ig, &buffer, 1) != 1) {
1372 if (i_io_read(ig, &buffer, 1) != 1) {
13711373 i_push_error(0, "failed skipping to image data offset");
13721374 return NULL;
13731375 }
14171419 }
14181420 i_plin(im, 0, xsize, y, line);
14191421 if (extras)
1420 ig->readcb(ig, junk, extras);
1422 i_io_read(ig, junk, extras);
14211423 y += yinc;
14221424 }
14231425 myfree(line);
2121
2222 mm_log((1,"i_conv(im %p, coeff %p, len %d)\n",im,coeff,len));
2323 i_clear_error();
24
25 if (len < 1) {
26 i_push_error(0, "there must be at least one coefficient");
27 return 0;
28 }
2429
2530 center=(len-1)/2;
2631
2121 btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
2222 btm->xsize=xsize;
2323 btm->ysize=ysize;
24 for(i=0;i<(xsize*ysize+8)/8;i++) btm->data[i]=0; /* Is this always needed */
24 memset(btm->data, 0, bytes);
2525 return btm;
2626 }
2727
317317 /*
318318 =item i_img_setmask(C<im>, C<ch_mask>)
319319 =category Image Information
320 =synopsis // only channel 0 writeable
320 =synopsis // only channel 0 writable
321321 =synopsis i_img_setmask(img, 0x01);
322322
323323 Set the image channel mask for C<im> to C<ch_mask>.
14881488 }
14891489 }
14901490
1491 /*
1492 =back
1493
1494 =head2 Stream reading and writing wrapper functions
1495
1496 =over
1497
1498 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1499
1500 Performs general read buffering for file readers that permit reading
1501 to be done through a callback.
1502
1503 The final callback gets two parameters, a I<need> value, and a I<want>
1504 value, where I<need> is the amount of data that the file library needs
1505 to read, and I<want> is the amount of space available in the buffer
1506 maintained by these functions.
1507
1508 This means if you need to read from a stream that you don't know the
1509 length of, you can return I<need> bytes, taking the performance hit of
1510 possibly expensive callbacks (eg. back to perl code), or if you are
1511 reading from a stream where it doesn't matter if some data is lost, or
1512 if the total length of the stream is known, you can return I<want>
1513 bytes.
1514
1515 =cut
1516 */
1517
1518 int
1519 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1520 int total;
1521
1522 if (length < gci->length - gci->cpos) {
1523 /* simplest case */
1524 memcpy(buf, gci->buffer+gci->cpos, length);
1525 gci->cpos += length;
1526 return length;
1527 }
1528
1529 total = 0;
1530 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1531 total += gci->length - gci->cpos;
1532 length -= gci->length - gci->cpos;
1533 buf += gci->length - gci->cpos;
1534 if (length < (int)sizeof(gci->buffer)) {
1535 int did_read;
1536 int copy_size;
1537 while (length
1538 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1539 sizeof(gci->buffer))) > 0) {
1540 gci->cpos = 0;
1541 gci->length = did_read;
1542
1543 copy_size = i_min(length, gci->length);
1544 memcpy(buf, gci->buffer, copy_size);
1545 gci->cpos += copy_size;
1546 buf += copy_size;
1547 total += copy_size;
1548 length -= copy_size;
1549 }
1550 }
1551 else {
1552 /* just read the rest - too big for our buffer*/
1553 int did_read;
1554 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1555 length -= did_read;
1556 total += did_read;
1557 buf += did_read;
1558 }
1559 }
1560 return total;
1561 }
1562
1563 /*
1564 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1565
1566 For use by callback file readers to initialize the reader buffer.
1567
1568 Allocates, initializes and returns the reader buffer.
1569
1570 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1571
1572 =cut
1573 */
1574 i_gen_read_data *
1575 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1576 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1577 self->cb = cb;
1578 self->userdata = userdata;
1579 self->length = 0;
1580 self->cpos = 0;
1581
1582 return self;
1583 }
1584
1585 /*
1586 =item i_free_gen_read_data(i_gen_read_data *)
1587
1588 Cleans up.
1589
1590 =cut
1591 */
1592 void i_free_gen_read_data(i_gen_read_data *self) {
1593 myfree(self);
1594 }
1595
1596 /*
1597 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1598
1599 Performs write buffering for a callback based file writer.
1600
1601 Failures are considered fatal, if a write fails then data will be
1602 dropped.
1603
1604 =cut
1605 */
1606 int
1607 i_gen_writer(
1608 i_gen_write_data *self,
1609 char const *data,
1610 int size)
1611 {
1612 if (self->filledto && self->filledto+size > self->maxlength) {
1613 if (self->cb(self->userdata, self->buffer, self->filledto)) {
1614 self->filledto = 0;
1615 }
1616 else {
1617 self->filledto = 0;
1618 return 0;
1619 }
1620 }
1621 if (self->filledto+size <= self->maxlength) {
1622 /* just save it */
1623 memcpy(self->buffer+self->filledto, data, size);
1624 self->filledto += size;
1625 return 1;
1626 }
1627 /* doesn't fit - hand it off */
1628 return self->cb(self->userdata, data, size);
1629 }
1630
1631 /*
1632 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1633
1634 Allocates and initializes the data structure used by i_gen_writer.
1635
1636 This should be released with L<image.c/i_free_gen_write_data>
1637
1638 =cut
1639 */
1640 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
1641 char *userdata, int max_length)
1642 {
1643 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
1644 self->cb = cb;
1645 self->userdata = userdata;
1646 self->maxlength = i_min(max_length, sizeof(self->buffer));
1647 if (self->maxlength < 0)
1648 self->maxlength = sizeof(self->buffer);
1649 self->filledto = 0;
1650
1651 return self;
1652 }
1653
1654 /*
1655 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
1656
1657 Cleans up the write buffer.
1658
1659 Will flush any left-over data if I<flush> is non-zero.
1660
1661 Returns non-zero if flush is zero or if info->cb() returns non-zero.
1662
1663 Return zero only if flush is non-zero and info->cb() returns zero.
1664 ie. if it fails.
1665
1666 =cut
1667 */
1668
1669 int i_free_gen_write_data(i_gen_write_data *info, int flush)
1670 {
1671 int result = !flush ||
1672 info->filledto == 0 ||
1673 info->cb(info->userdata, info->buffer, info->filledto);
1674 myfree(info);
1675
1676 return result;
1677 }
1678
16791491 struct magic_entry {
16801492 unsigned char *magic;
16811493 size_t magic_size;
18001612 unsigned char head[18];
18011613 ssize_t rc;
18021614
1803 io_glue_commit_types(data);
1804 rc = data->readcb(data, head, 18);
1615 rc = i_io_peekn(data, head, 18);
18051616 if (rc == -1) return NULL;
1806 data->seekcb(data, -rc, SEEK_CUR);
1617 #if 0
1618 {
1619 int i;
1620 fprintf(stderr, "%d bytes -", (int)rc);
1621 for (i = 0; i < rc; ++i)
1622 fprintf(stderr, " %02x", head[i]);
1623 fprintf(stderr, "\n");
1624 }
1625 #endif
18071626
18081627 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
18091628 struct magic_entry const *entry = formats + i;
244244 size_t name_buf_size);
245245
246246 #endif /* End of freetype headers */
247
248 /* functions for reading and writing formats */
249
250 /* general reader callback
251 userdata - data the user passed into the reader
252 buffer - the buffer to fill with data
253 need - the amount of data needed
254 want - the amount of space we have to store data
255 fill buffer and return the number of bytes read, 0 for eof, -1 for error
256 */
257
258 typedef int (*i_read_callback_t)(char *userdata, char *buffer, int need,
259 int want);
260
261 /* i_gen_reader() translates the low-level requests from whatever library
262 into buffered requests.
263 but the called function can always bypass buffering by only ever
264 reading I<need> bytes.
265 */
266 #define CBBUFSIZ 4096
267
268 typedef struct {
269 i_read_callback_t cb;
270 char *userdata;
271 char buffer[CBBUFSIZ];
272 int length;
273 int cpos;
274 } i_gen_read_data;
275
276 extern int i_gen_reader(i_gen_read_data *info, char *buffer, int need);
277 extern i_gen_read_data *i_gen_read_data_new(i_read_callback_t cb, char *userdata);
278 extern void i_free_gen_read_data(i_gen_read_data *);
279
280 /* general writer callback
281 userdata - the data the user passed into the writer
282 data - the data to write
283 data_size - the number of bytes to write
284 write the data, return non-zero on success, zero on failure.
285 */
286 typedef int (*i_write_callback_t)(char *userdata, char const *data, int size);
287
288 typedef struct {
289 i_write_callback_t cb;
290 char *userdata;
291 char buffer[CBBUFSIZ];
292 int maxlength;
293 int filledto;
294 } i_gen_write_data;
295
296 extern int i_gen_writer(i_gen_write_data *info, char const *data, int size);
297 extern i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, char *userdata, int maxlength);
298 extern int i_free_gen_write_data(i_gen_write_data *, int flush);
299247
300248 extern void i_quant_makemap(i_quantize *quant, i_img **imgs, int count);
301249 extern i_palidx *i_quant_translate(i_quantize *quant, i_img *img);
607607 od_custom /* custom 8x8 map */
608608 } i_ord_dith;
609609
610 typedef struct i_gif_pos_tag {
611 int x, y;
612 } i_gif_pos;
613
614610 /* passed into i_writegif_gen() to control quantization */
615611 typedef struct i_quantize_tag {
616612 int version;
653649 /* version 2 members after here */
654650 } i_quantize;
655651
656 typedef struct i_gif_opts {
657 /* each image has a local color map */
658 int each_palette;
659
660 /* images are interlaced */
661 int interlace;
662
663 /* time for which image is displayed
664 (in 1/100 seconds)
665 default: 0
666 */
667 int delay_count;
668 int *delays;
669
670 /* user input flags
671 default: 0
672 */
673 int user_input_count;
674 char *user_input_flags;
675
676 /* disposal
677 default: 0 */
678 int disposal_count;
679 char *disposal;
680
681 /* this is added to the color table when we make an image transparent */
682 i_color tran_color;
683
684 /* image positions */
685 int position_count;
686 i_gif_pos *positions;
687
688 /* Netscape loop extension - number of loops */
689 int loop_count;
690
691 /* should be eliminate unused colors? */
692 int eliminate_unused;
693 } i_gif_opts;
694
695652 /* distance measures used by some filters */
696653 enum {
697654 i_dmeasure_euclidean = 0,
711668 #define I_FORMAT_ATTR(format_index, va_index)
712669 #endif
713670
671 #ifdef _MSC_VER
672 # ifndef vsnprintf
673 # define vsnprintf _vsnprintf
674 # endif
675 # ifndef snprintf
676 # define snprintf _snprintf
677 # endif
678 #endif
679
714680 /*
715681 =item i_DF
716682 =category Data Types
130130 i_render_color,
131131 i_render_fill,
132132 i_render_line,
133 i_render_linef
133 i_render_linef,
134
135 /* level 6 */
136 i_io_getc_imp,
137 i_io_peekc_imp,
138 i_io_peekn,
139 i_io_putc_imp,
140 i_io_read,
141 i_io_write,
142 i_io_seek,
143 i_io_flush,
144 i_io_close,
145 i_io_set_buffered,
146 i_io_gets,
147 io_new_fd,
148 io_new_bufchain,
149 io_new_buffer,
150 io_new_cb,
151 io_slurp,
152 io_glue_destroy
134153 };
135154
136155 /* in general these functions aren't called by Imager internally, but
233233 #define i_render_linef(r, x, y, width, src, line, combine) \
234234 ((im_extt->f_i_render_linef)((r), (x), (y), (width), (src), (line), (combine)))
235235
236 #define i_io_getc_imp (im_extt->f_i_io_getc_imp)
237 #define i_io_peekc_imp (im_extt->f_i_io_peekc_imp)
238 #define i_io_peekn (im_extt->f_i_io_peekn)
239 #define i_io_putc_imp (im_extt->f_i_io_putc_imp)
240 #define i_io_read (im_extt->f_i_io_read)
241 #define i_io_write (im_extt->f_i_io_write)
242 #define i_io_seek (im_extt->f_i_io_seek)
243 #define i_io_flush (im_extt->f_i_io_flush)
244 #define i_io_close (im_extt->f_i_io_close)
245 #define i_io_set_buffered (im_extt->f_i_io_set_buffered)
246 #define i_io_gets (im_extt->f_i_io_gets)
247 #define io_new_fd(fd) ((im_extt->f_io_new_fd)(fd))
248 #define io_new_bufchain() ((im_extt->f_io_new_bufchain)())
249 #define io_new_buffer(data, len, closecb, closedata) \
250 ((im_extt->f_io_new_buffer)((data), (len), (closecb), (closedata)))
251 #define io_new_cb(p, readcb, writecb, seekcb, closecb, destroycb) \
252 ((im_extt->f_io_new_cb)((p), (readcb), (writecb), (seekcb), (closecb), (destroycb)))
253 #define io_slurp(ig, datap) ((im_extt->f_io_slurp)((ig), (datap)))
254 #define io_glue_destroy(ig) ((im_extt->f_io_glue_destroy)(ig))
255
236256 #ifdef IMAGER_LOG
237257 #define mm_log(x) { i_lhead(__FILE__,__LINE__); i_loog x; }
238258 #else
1313 Version 2 changed the types of some parameters and pointers. A
1414 simple recompile should be enough in most cases.
1515
16 Version 3 changed the behaviour of some of the I/O layer functions,
17 and in some cases the initial seek position when calling file
18 readers. Switching away from calling readcb etc to i_io_read() etc
19 should fix your code.
20
1621 */
17 #define IMAGER_API_VERSION 2
22 #define IMAGER_API_VERSION 3
1823
1924 /*
2025 IMAGER_API_LEVEL is the level of the structure. New function pointers
2227 will result in an increment of IMAGER_API_LEVEL.
2328 */
2429
25 #define IMAGER_API_LEVEL 6
30 #define IMAGER_API_LEVEL 7
2631
2732 typedef struct {
2833 int version;
184189 i_img_dim width, const double *src,
185190 i_fcolor *line, i_fill_combinef_f combine);
186191
187 /* IMAGER_API_LEVEL 6 functions will be added here */
192 /* Level 6 lost to mis-numbering */
193 /* IMAGER_API_LEVEL 7 */
194 int (*f_i_io_getc_imp)(io_glue *ig);
195 int (*f_i_io_peekc_imp)(io_glue *ig);
196 ssize_t (*f_i_io_peekn)(io_glue *ig, void *buf, size_t size);
197 int (*f_i_io_putc_imp)(io_glue *ig, int c);
198 ssize_t (*f_i_io_read)(io_glue *, void *buf, size_t size);
199 ssize_t (*f_i_io_write)(io_glue *, const void *buf, size_t size);
200 off_t (*f_i_io_seek)(io_glue *, off_t offset, int whence);
201 int (*f_i_io_flush)(io_glue *ig);
202 int (*f_i_io_close)(io_glue *ig);
203 int (*f_i_io_set_buffered)(io_glue *ig, int buffered);
204 ssize_t (*f_i_io_gets)(io_glue *ig, char *, size_t, int);
205
206 i_io_glue_t *(*f_io_new_fd)(int fd);
207 i_io_glue_t *(*f_io_new_bufchain)(void);
208 i_io_glue_t *(*f_io_new_buffer)(const char *data, size_t len, i_io_closebufp_t closecb, void *closedata);
209 i_io_glue_t *(*f_io_new_cb)(void *p, i_io_readl_t readcb, i_io_writel_t writecb, i_io_seekl_t seekcb, i_io_closel_t closecb, i_io_destroyl_t destroycb);
210 size_t (*f_io_slurp)(i_io_glue_t *ig, unsigned char **c);
211 void (*f_io_glue_destroy)(i_io_glue_t *ig);
212
213 /* IMAGER_API_LEVEL 8 functions will be added here */
214
188215 } im_ext_funcs;
189216
190217 #define PERL_FUNCTION_TABLE_NAME "Imager::__ext_func_table"
244244 }
245245 }
246246 if(defined($args{INC})) {
247 foreach my $arg (split(' ', $args{INC})) {
247 foreach my $arg (_shellwords($args{INC})) {
248248 die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
249249 push @incpaths, substr($arg, 2);
250250 }
251251 }
252252
253 my @cc = _findcc();
253 my ($cc, $ld) = _findcc();
254254 my @missing;
255255 my @wrongresult;
256256 my @use_headers;
270270 if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
271271 require Win32;
272272 @sys_cmd = (
273 @cc,
273 @$cc,
274274 $cfile,
275275 "/Fe$exefile",
276 (map { '/I'.Win32::GetShortPathName($_) } @incpaths)
276 (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
277 "/link",
278 @$ld
277279 );
278280 } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
279281 @sys_cmd = (
280 @cc,
282 @$cc,
281283 (map { "-I$_" } @incpaths),
282284 "-o$exefile",
283 $cfile
285 $cfile,
286 @$ld
284287 );
285288 } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
286289 @sys_cmd = (
287 @cc,
290 @$cc,
291 @$ld,
288292 $cfile,
289293 (map { "-I$_" } @incpaths),
290294 "-o", "$exefile"
316320 } @libpaths;
317321 # this is horribly sensitive to the order of arguments
318322 @sys_cmd = (
319 @cc,
323 @$cc,
320324 $cfile,
321325 ( map { "$_.lib" } @$libs ),
322326 "/Fe$exefile",
323327 (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
324328 "/link",
329 @$ld,
325330 (map {'/libpath:'.Win32::GetShortPathName($_)} @$paths),
326331 );
327332 } elsif($Config{cc} eq 'CC/DECC') { # VMS
328333 } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
329334 @sys_cmd = (
330 @cc,
335 @$cc,
336 @$ld,
331337 "-o$exefile",
332338 (map { "-l$_" } @$libs ),
333339 (map { "-I$_" } @incpaths),
336342 } else { # Unix-ish
337343 # gcc, Sun, AIX (gcc, cc)
338344 @sys_cmd = (
339 @cc,
345 @$cc,
346 @$ld,
340347 $cfile,
341348 "-o", "$exefile",
342349 (map { "-l$_" } @$libs ),
367374 unlink $exefile if -f $exefile;
368375 unlink $ofile if -f $ofile;
369376 unlink "$exefile\.manifest" if -f "$exefile\.manifest";
377 if ( $Config{cc} eq 'cl' ) {
378 # MSVC also creates foo.ilk and foo.pdb
379 my $ilkfile = $exefile;
380 $ilkfile =~ s/$Config{_exe}$/.ilk/;
381 my $pdbfile = $exefile;
382 $pdbfile =~ s/$Config{_exe}$/.pdb/;
383 unlink $ilkfile if -f $ilkfile;
384 unlink $pdbfile if -f $pdbfile;
385 }
370386 return
371387 }
372
388
389 # return ($cc, $ld)
390 # where $cc is an array ref of compiler name, compiler flags
391 # where $ld is an array ref of linker flags
373392 sub _findcc {
374393 # Need to use $keep=1 to work with MSWin32 backslashes and quotes
375 my @Config_ccflags_ldflags = @Config{qw(ccflags ldflags)}; # use copy so ASPerl will compile
376 my @flags = grep { length } map { quotewords('\s+', 1, $_ || ()) } @Config_ccflags_ldflags;
394 my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
395 my @Config_ldflags = @Config{qw(ldflags perllibs)};
396 my @ccflags = grep { length } quotewords('\s+', 1, $Config_ccflags);
397 my @ldflags = grep { length } quotewords('\s+', 1, @Config_ldflags);
377398 my @paths = split(/$Config{path_sep}/, $ENV{PATH});
378399 my @cc = split(/\s+/, $Config{cc});
379 return (@cc, @flags) if -x $cc[0];
400 return ( [ @cc, @ccflags ], \@ldflags ) if -x $cc[0];
380401 foreach my $path (@paths) {
381402 my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
382 return ($compiler, @cc[1 .. $#cc], @flags) if -x $compiler;
403 return ([ $compiler, @cc[1 .. $#cc], @ccflags ], \@ldflags)
404 if -x $compiler;
383405 }
384406 die("Couldn't find your C compiler\n");
407 }
408
409 sub _shellwords {
410 my $line = shift;
411
412 if ($^O eq "MSWin32") {
413 my @elements;
414 $line =~ s/^\s+//;
415 while ($line =~ s/^"([^"]*)"// || $line =~ s/^(\S+)//) {
416 push @elements, $1;
417 $line =~ s/^\s+//;
418 }
419 return @elements;
420 }
421 else {
422 return grep defined && /\S/, quotewords('\s+', 0, $line);
423 }
385424 }
386425
387426 # code substantially borrowed from IPC::Run3
+1234
-461
iolayer.c less more
1111 #include "imageri.h"
1212
1313 #define IOL_DEB(x)
14
14 #define IOL_DEBs stderr
15
16 #define IO_BUF_SIZE 8192
1517
1618 char *io_type_names[] = { "FDSEEK", "FDNOSEEK", "BUFFER", "CBSEEK", "CBNOSEEK", "BUFCHAIN" };
1719
2426 } io_blink;
2527
2628
27 /* Structures that describe callback interfaces */
28
2929 typedef struct {
30 off_t offset;
30 i_io_glue_t base;
31 int fd;
32 } io_fdseek;
33
34 typedef struct {
35 i_io_glue_t base;
36 const char *data;
37 size_t len;
38 i_io_closebufp_t closecb; /* free memory mapped segment or decrement refcount */
39 void *closedata;
3140 off_t cpos;
32 } io_ex_rseek;
33
41 } io_buffer;
3442
3543 typedef struct {
36 off_t offset;
37 off_t cpos;
38 io_blink *head;
39 io_blink *tail;
40 io_blink *cp;
41 } io_ex_fseek;
42
44 i_io_glue_t base;
45 void *p; /* Callback data */
46 i_io_readl_t readcb;
47 i_io_writel_t writecb;
48 i_io_seekl_t seekcb;
49 i_io_closel_t closecb;
50 i_io_destroyl_t destroycb;
51 } io_cb;
4352
4453 typedef struct {
4554 off_t offset; /* Offset of the source - not used */
5261 off_t gpos; /* Global position in stream */
5362 } io_ex_bchain;
5463
55 typedef struct {
56 off_t offset; /* Offset of the source - not used */
57 off_t cpos; /* Offset within the current */
58 } io_ex_buffer;
59
60 static void io_obj_setp_buffer(io_obj *io, char *p, size_t len, i_io_closebufp_t closecb, void *closedata);
61 static void io_obj_setp_cb2 (io_obj *io, void *p, i_io_readl_t readcb, i_io_writel_t writecb, i_io_seekl_t seekcb, i_io_closel_t closecb, i_io_destroyl_t destroycb);
62
6364 /* turn current offset, file length, whence and offset into a new offset */
6465 #define calc_seek_offset(curr_off, length, offset, whence) \
6566 (((whence) == SEEK_SET) ? (offset) : \
7576
7677 io_glue *ig = io_new_fd( fileno(stdin) );
7778 method = io_reqmeth( IOL_NOSEEK | IOL_MMAP ); // not implemented yet
78 io_glue_commit_types(ig); // always assume IOL_SEEK for now
79
7980 switch (method) {
8081 case IOL_NOSEEK:
8182 code that uses ig->readcb()
110111 =cut
111112 */
112113
114 static void
115 i_io_init(io_glue *ig, int type, i_io_readp_t readcb, i_io_writep_t writecb,
116 i_io_seekp_t seekcb);
117
113118 static ssize_t fd_read(io_glue *ig, void *buf, size_t count);
114119 static ssize_t fd_write(io_glue *ig, const void *buf, size_t count);
115120 static off_t fd_seek(io_glue *ig, off_t offset, int whence);
116121 static int fd_close(io_glue *ig);
117122 static ssize_t fd_size(io_glue *ig);
118123 static const char *my_strerror(int err);
124 static void i_io_setup_buffer(io_glue *ig);
125 static void
126 i_io_start_write(io_glue *ig);
127 static int
128 i_io_read_fill(io_glue *ig, ssize_t needed);
129 static void
130 dump_data(unsigned char *start, unsigned char *end, int bias);
131 static ssize_t realseek_read(io_glue *igo, void *buf, size_t count);
132 static ssize_t realseek_write(io_glue *igo, const void *buf, size_t count);
133 static int realseek_close(io_glue *igo);
134 static off_t realseek_seek(io_glue *igo, off_t offset, int whence);
135 static void realseek_destroy(io_glue *igo);
136 static ssize_t buffer_read(io_glue *igo, void *buf, size_t count);
137 static ssize_t buffer_write(io_glue *ig, const void *buf, size_t count);
138 static int buffer_close(io_glue *ig);
139 static off_t buffer_seek(io_glue *igo, off_t offset, int whence);
140 static void buffer_destroy(io_glue *igo);
141 static io_blink*io_blink_new(void);
142 static void io_bchain_advance(io_ex_bchain *ieb);
143 static void io_destroy_bufchain(io_ex_bchain *ieb);
144 static ssize_t bufchain_read(io_glue *ig, void *buf, size_t count);
145 static ssize_t bufchain_write(io_glue *ig, const void *buf, size_t count);
146 static int bufchain_close(io_glue *ig);
147 static off_t bufchain_seek(io_glue *ig, off_t offset, int whence);
148 static void bufchain_destroy(io_glue *ig);
149
150 /*
151 * Methods for setting up data source
152 */
153
154 /*
155 =item io_new_bufchain()
156 =order 10
157 =category I/O Layers
158
159 returns a new io_glue object that has the 'empty' source and but can
160 be written to and read from later (like a pseudo file).
161
162 =cut
163 */
164
165 io_glue *
166 io_new_bufchain() {
167 io_glue *ig;
168 io_ex_bchain *ieb = mymalloc(sizeof(io_ex_bchain));
169
170 mm_log((1, "io_new_bufchain()\n"));
171
172 ig = mymalloc(sizeof(io_glue));
173 memset(ig, 0, sizeof(*ig));
174 i_io_init(ig, BUFCHAIN, bufchain_read, bufchain_write, bufchain_seek);
175
176 ieb->offset = 0;
177 ieb->length = 0;
178 ieb->cpos = 0;
179 ieb->gpos = 0;
180 ieb->tfill = 0;
181
182 ieb->head = io_blink_new();
183 ieb->cp = ieb->head;
184 ieb->tail = ieb->head;
185
186 ig->exdata = ieb;
187 ig->closecb = bufchain_close;
188 ig->destroycb = bufchain_destroy;
189
190 return ig;
191 }
192
193 /*
194 =item io_new_buffer(data, length)
195 =order 10
196 =category I/O Layers
197
198 Returns a new io_glue object that has the source defined as reading
199 from specified buffer. Note that the buffer is not copied.
200
201 data - buffer to read from
202 length - length of buffer
203
204 =cut
205 */
206
207 io_glue *
208 io_new_buffer(const char *data, size_t len, i_io_closebufp_t closecb, void *closedata) {
209 io_buffer *ig;
210
211 mm_log((1, "io_new_buffer(data %p, len %ld, closecb %p, closedata %p)\n", data, (long)len, closecb, closedata));
212
213 ig = mymalloc(sizeof(io_buffer));
214 memset(ig, 0, sizeof(*ig));
215 i_io_init(&ig->base, BUFFER, buffer_read, buffer_write, buffer_seek);
216 ig->data = data;
217 ig->len = len;
218 ig->closecb = closecb;
219 ig->closedata = closedata;
220
221 ig->cpos = 0;
222
223 ig->base.closecb = buffer_close;
224 ig->base.destroycb = buffer_destroy;
225
226 return (io_glue *)ig;
227 }
228
229
230 /*
231 =item io_new_fd(fd)
232 =order 10
233 =category I/O Layers
234
235 returns a new io_glue object that has the source defined as reading
236 from specified file descriptor. Note that the the interface to receiving
237 data from the io_glue callbacks hasn't been done yet.
238
239 fd - file descriptor to read/write from
240
241 =cut
242 */
243
244 io_glue *
245 io_new_fd(int fd) {
246 io_fdseek *ig;
247
248 mm_log((1, "io_new_fd(fd %d)\n", fd));
249
250 ig = mymalloc(sizeof(io_fdseek));
251 memset(ig, 0, sizeof(*ig));
252 i_io_init(&ig->base, FDSEEK, fd_read, fd_write, fd_seek);
253 ig->fd = fd;
254
255 ig->base.closecb = fd_close;
256 ig->base.sizecb = fd_size;
257 ig->base.destroycb = NULL;
258
259 mm_log((1, "(%p) <- io_new_fd\n", ig));
260 return (io_glue *)ig;
261 }
262
263 /*
264 =item io_new_cb(p, read_cb, write_cb, seek_cb, close_cb, destroy_cb)
265 =category I/O Layers
266 =order 10
267
268 Create a new I/O layer object that calls your supplied callbacks.
269
270 In general the callbacks should behave like the corresponding POSIX
271 primitives.
272
273 =over
274
275 =item *
276
277 C<read_cb>(p, buffer, length) should read up to C<length> bytes into
278 C<buffer> and return the number of bytes read. At end of file, return
279 0. On error, return -1.
280
281 =item *
282
283 C<write_cb>(p, buffer, length) should write up to C<length> bytes from
284 C<buffer> and return the number of bytes written. A return value <= 0
285 will be treated as an error.
286
287 =item *
288
289 C<seekcb>(p, offset, whence) should seek and return the new offset.
290
291 =item *
292
293 C<close_cb>(p) should return 0 on success, -1 on failure.
294
295 =item *
296
297 C<destroy_cb>(p) should release any memory specific to your callback
298 handlers.
299
300 =back
301
302 =cut
303 */
304
305 io_glue *
306 io_new_cb(void *p, i_io_readl_t readcb, i_io_writel_t writecb,
307 i_io_seekl_t seekcb, i_io_closel_t closecb,
308 i_io_destroyl_t destroycb) {
309 io_cb *ig;
310
311 mm_log((1, "io_new_cb(p %p, readcb %p, writecb %p, seekcb %p, closecb %p, "
312 "destroycb %p)\n", p, readcb, writecb, seekcb, closecb, destroycb));
313 ig = mymalloc(sizeof(io_cb));
314 memset(ig, 0, sizeof(*ig));
315 i_io_init(&ig->base, CBSEEK, realseek_read, realseek_write, realseek_seek);
316 mm_log((1, "(%p) <- io_new_cb\n", ig));
317
318 ig->base.closecb = realseek_close;
319 ig->base.destroycb = realseek_destroy;
320
321 ig->p = p;
322 ig->readcb = readcb;
323 ig->writecb = writecb;
324 ig->seekcb = seekcb;
325 ig->closecb = closecb;
326 ig->destroycb = destroycb;
327
328 return (io_glue *)ig;
329 }
330
331 /*
332 =item io_slurp(ig, c)
333 =category I/O Layers
334
335 Takes the source that the io_glue is bound to and allocates space for
336 a return buffer and returns the entire content in a single buffer.
337 Note: This only works for io_glue objects created by
338 io_new_bufchain(). It is useful for saving to scalars and such.
339
340 ig - io_glue object
341 c - pointer to a pointer to where data should be copied to
342
343 char *data;
344 size_t size = io_slurp(ig, &data);
345 ... do something with the data ...
346 myfree(data);
347
348 io_slurp() will abort the program if the supplied I/O layer is not
349 from io_new_bufchain().
350
351 =cut
352 */
353
354 size_t
355 io_slurp(io_glue *ig, unsigned char **c) {
356 ssize_t rc;
357 off_t orgoff;
358 io_ex_bchain *ieb;
359 unsigned char *cc;
360 io_type inn = ig->type;
361
362 if ( inn != BUFCHAIN ) {
363 i_fatal(0, "io_slurp: called on a source that is not from a bufchain\n");
364 }
365
366 ieb = ig->exdata;
367 cc = *c = mymalloc( ieb->length );
368
369 orgoff = ieb->gpos;
370
371 bufchain_seek(ig, 0, SEEK_SET);
372
373 rc = bufchain_read(ig, cc, ieb->length);
374
375 if (rc != ieb->length)
376 i_fatal(1, "io_slurp: bufchain_read returned an incomplete read: rc = %d, request was %d\n", rc, ieb->length);
377
378 return rc;
379 }
380
381 /*
382 =item io_glue_destroy(ig)
383 =category I/O Layers
384 =order 90
385 =synopsis io_glue_destroy(ig);
386
387 Destroy an io_glue objects. Should clean up all related buffers.
388
389 ig - io_glue object to destroy.
390
391 =cut
392 */
393
394 void
395 io_glue_destroy(io_glue *ig) {
396 mm_log((1, "io_glue_DESTROY(ig %p)\n", ig));
397
398 if (ig->destroycb)
399 ig->destroycb(ig);
400
401 if (ig->buffer)
402 myfree(ig->buffer);
403
404 myfree(ig);
405 }
406
407 /*
408 =item i_io_getc(ig)
409 =category I/O Layers
410
411 A macro to read a single byte from a buffered I/O glue object.
412
413 Returns EOF on failure, or a byte.
414
415 =cut
416 */
417
418 int
419 i_io_getc_imp(io_glue *ig) {
420 if (ig->write_ptr)
421 return EOF;
422
423 if (ig->error || ig->buf_eof)
424 return EOF;
425
426 if (!ig->buffered) {
427 unsigned char buf;
428 ssize_t rc = i_io_raw_read(ig, &buf, 1);
429 if (rc > 0) {
430 return buf;
431 }
432 else if (rc == 0) {
433 ig->buf_eof = 1;
434 return EOF;
435 }
436 else {
437 ig->error = 1;
438 return EOF;
439 }
440 }
441
442 if (!ig->buffer)
443 i_io_setup_buffer(ig);
444
445 if (!ig->read_ptr || ig->read_ptr == ig->read_end) {
446 if (!i_io_read_fill(ig, 1))
447 return EOF;
448 }
449
450 return *(ig->read_ptr++);
451 }
452
453 /*
454 =item i_io_peekc(ig)
455 =category I/O Layers
456
457 Read the next character from the stream without advancing the stream.
458
459 On error or end of file, return EOF.
460
461 For unbuffered streams a single character buffer will be setup.
462
463 =cut
464 */
465
466 int
467 i_io_peekc_imp(io_glue *ig) {
468 if (ig->write_ptr)
469 return EOF;
470
471 if (!ig->buffer)
472 i_io_setup_buffer(ig);
473
474 if (!ig->buffered) {
475 ssize_t rc = i_io_raw_read(ig, ig->buffer, 1);
476 if (rc > 0) {
477 ig->read_ptr = ig->buffer;
478 ig->read_end = ig->buffer + 1;
479 return *(ig->buffer);
480 }
481 else if (rc == 0) {
482 ig->buf_eof = 1;
483 return EOF;
484 }
485 else {
486 ig->error = 1;
487 return EOF;
488 }
489 }
490
491 if (!ig->read_ptr || ig->read_ptr == ig->read_end) {
492 if (ig->error || ig->buf_eof)
493 return EOF;
494
495 if (!i_io_read_fill(ig, 1))
496 return EOF;
497 }
498
499 return *(ig->read_ptr);
500 }
501
502 /*
503 =item i_io_peekn(ig, buffer, size)
504 =category I/O Layers
505 =synopsis ssize_t count = i_io_peekn(ig, buffer, sizeof(buffer));
506
507 Buffer at least C<size> (at most C<< ig->buf_size >> bytes of data
508 from the stream and return C<size> bytes of it to the caller in
509 C<buffer>.
510
511 This ignores the buffered state of the stream, and will always setup
512 buffering if needed.
513
514 If no C<type> parameter is provided to Imager::read() or
515 Imager::read_multi(), Imager will call C<i_io_peekn()> when probing
516 for the file format.
517
518 Returns -1 on error, 0 if there is no data before EOF, or the number
519 of bytes read into C<buffer>.
520
521 =cut
522 */
523
524 ssize_t
525 i_io_peekn(io_glue *ig, void *buf, size_t size) {
526 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn(%p, %p, %d)\n", ig, buf, (int)size));
527
528 if (size == 0) {
529 i_push_error(0, "peekn size must be positive");
530 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() => -1 (zero size)\n"));
531 return -1;
532 }
533
534 if (ig->write_ptr) {
535 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() => -1 (write_ptr set)\n"));
536 return -1;
537 }
538
539 if (!ig->buffer)
540 i_io_setup_buffer(ig);
541
542 if ((!ig->read_ptr || size > ig->read_end - ig->read_ptr)
543 && !(ig->buf_eof || ig->error)) {
544 i_io_read_fill(ig, size);
545 }
546
547 if (size > ig->read_end - ig->read_ptr)
548 size = ig->read_end - ig->read_ptr;
549
550 if (size)
551 memcpy(buf, ig->read_ptr, size);
552 else if (ig->buf_eof) {
553 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() => 0 (eof)\n"));
554 return 0;
555 }
556 else if (ig->error) {
557 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() => -1 (error)\n"));
558 return -1;
559 }
560 else {
561 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() - size 0 but not eof or error!\n"));
562 return -1;
563 }
564
565 IOL_DEB(fprintf(IOL_DEBs, "i_io_peekn() => %d\n", (int)size));
566
567 return size;
568 }
569
570 /*
571 =item i_io_putc(ig, c)
572 =category I/O Layers
573
574 Write a single character to the stream.
575
576 On success return c, on error returns EOF
577
578 =cut
579 */
580
581 int
582 i_io_putc_imp(io_glue *ig, int c) {
583 IOL_DEB(fprintf(IOL_DEBs, "i_io_putc_imp(%p, %d)\n", ig, c));
584
585 if (!ig->buffered) {
586 char buf = c;
587 ssize_t write_result;
588 int result = c;
589
590 if (ig->error)
591 return EOF;
592
593 write_result = i_io_raw_write(ig, &buf, 1);
594 if (write_result != 1) {
595 ig->error = 1;
596 result = EOF;
597 IOL_DEB(fprintf(IOL_DEBs, " unbuffered putc() failed, setting error mode\n"));
598 }
599 IOL_DEB(fprintf(IOL_DEBs, " unbuffered: result %d\n", result));
600
601 return result;
602 }
603
604 if (ig->read_ptr)
605 return EOF;
606
607 if (ig->error)
608 return EOF;
609
610 if (!ig->buffer)
611 i_io_setup_buffer(ig);
612
613 if (ig->write_ptr && ig->write_ptr == ig->write_end) {
614 if (!i_io_flush(ig))
615 return EOF;
616 }
617
618 i_io_start_write(ig);
619
620 *(ig->write_ptr)++ = c;
621
622 return (unsigned char)c;
623 }
624
625 /*
626 =item i_io_read(io, buffer, size)
627 =category I/O Layers
628
629 Read up to C<size> bytes from the stream C<io> into C<buffer>.
630
631 Returns the number of bytes read. Returns 0 on end of file. Returns
632 -1 on error.
633
634 =cut
635 */
636
637 ssize_t
638 i_io_read(io_glue *ig, void *buf, size_t size) {
639 unsigned char *pbuf = buf;
640 ssize_t read_total = 0;
641
642 IOL_DEB(fprintf(IOL_DEBs, "i_io_read(%p, %p, %u)\n", ig, buf, (unsigned)size));
643
644 if (ig->write_ptr) {
645 IOL_DEB(fprintf(IOL_DEBs, "i_io_read() => -1 (write_ptr set)\n"));
646 return -1;
647 }
648
649 if (!ig->buffer && ig->buffered)
650 i_io_setup_buffer(ig);
651
652 if (ig->read_ptr && ig->read_ptr < ig->read_end) {
653 size_t alloc = ig->read_end - ig->read_ptr;
654
655 if (alloc > size)
656 alloc = size;
657
658 memcpy(pbuf, ig->read_ptr, alloc);
659 ig->read_ptr += alloc;
660 pbuf += alloc;
661 size -= alloc;
662 read_total += alloc;
663 }
664
665 if (size > 0 && !(ig->error || ig->buf_eof)) {
666 if (!ig->buffered || size > ig->buf_size) {
667 ssize_t rc;
668
669 while (size > 0 && (rc = i_io_raw_read(ig, pbuf, size)) > 0) {
670 size -= rc;
671 pbuf += rc;
672 read_total += rc;
673 }
674
675 IOL_DEB(fprintf(IOL_DEBs, "i_io_read() => %d (raw read)\n", (int)read_total));
676
677 if (rc < 0)
678 ig->error = 1;
679 else if (rc == 0)
680 ig->buf_eof = 1;
681
682 if (!read_total)
683 return rc;
684 }
685 else {
686 if (i_io_read_fill(ig, size)) {
687 size_t alloc = ig->read_end - ig->read_ptr;
688 if (alloc > size)
689 alloc = size;
690
691 memcpy(pbuf, ig->read_ptr, alloc);
692 ig->read_ptr += alloc;
693 pbuf += alloc;
694 size -= alloc;
695 read_total += alloc;
696 }
697 else {
698 if (!read_total && ig->error) {
699 IOL_DEB(fprintf(IOL_DEBs, "i_io_read() => -1 (fill failure)\n"));
700 return -1;
701 }
702 }
703 }
704 }
705
706 if (!read_total && ig->error)
707 read_total = -1;
708
709 IOL_DEB(fprintf(IOL_DEBs, "i_io_read() => %d\n", (int)read_total));
710
711 return read_total;
712 }
713
714 /*
715 =item i_io_write(io, buffer, size)
716 =category I/O Layers
717 =synopsis ssize_t result = i_io_write(io, buffer, size)
718
719 Write to the given I/O stream.
720
721 Returns the number of bytes written.
722
723 =cut
724 */
725
726 ssize_t
727 i_io_write(io_glue *ig, const void *buf, size_t size) {
728 const unsigned char *pbuf = buf;
729 size_t write_count = 0;
730
731 IOL_DEB(fprintf(IOL_DEBs, "i_io_write(%p, %p, %u)\n", ig, buf, (unsigned)size));
732
733 if (!ig->buffered) {
734 ssize_t result;
735
736 if (ig->error) {
737 IOL_DEB(fprintf(IOL_DEBs, " unbuffered, error state\n"));
738 return -1;
739 }
740
741 result = i_io_raw_write(ig, buf, size);
742
743 if (result != size) {
744 ig->error = 1;
745 IOL_DEB(fprintf(IOL_DEBs, " unbuffered, setting error flag\n"));
746 }
747
748 IOL_DEB(fprintf(IOL_DEBs, " unbuffered, result: %d\n", (int)result));
749
750 return result;
751 }
752
753 if (ig->read_ptr) {
754 IOL_DEB(fprintf(IOL_DEBs, "i_io_write() => -1 (read_ptr set)\n"));
755 return -1;
756 }
757
758 if (ig->error) {
759 IOL_DEB(fprintf(IOL_DEBs, "i_io_write() => -1 (error)\n"));
760 return -1;
761 }
762
763 if (!ig->buffer)
764 i_io_setup_buffer(ig);
765
766 if (!ig->write_ptr)
767 i_io_start_write(ig);
768
769 if (ig->write_ptr && ig->write_ptr + size <= ig->write_end) {
770 size_t alloc = ig->write_end - ig->write_ptr;
771 if (alloc > size)
772 alloc = size;
773 memcpy(ig->write_ptr, pbuf, alloc);
774 write_count += alloc;
775 size -= alloc;
776 pbuf += alloc;
777 ig->write_ptr += alloc;
778 }
779
780 if (size) {
781 if (!i_io_flush(ig)) {
782 IOL_DEB(fprintf(IOL_DEBs, "i_io_write() => %d (i_io_flush failure)\n", (int)write_count));
783 return write_count ? write_count : -1;
784 }
785
786 i_io_start_write(ig);
787
788 if (size > ig->buf_size) {
789 ssize_t rc;
790 while (size > 0 && (rc = i_io_raw_write(ig, pbuf, size)) > 0) {
791 write_count += rc;
792 pbuf += rc;
793 size -= rc;
794 }
795 if (rc <= 0) {
796 ig->error = 1;
797 if (!write_count) {
798 IOL_DEB(fprintf(IOL_DEBs, "i_io_write() => -1 (direct write failure)\n"));
799 return -1;
800 }
801 }
802 }
803 else {
804 memcpy(ig->write_ptr, pbuf, size);
805 write_count += size;
806 ig->write_ptr += size;
807 }
808 }
809
810 IOL_DEB(fprintf(IOL_DEBs, "i_io_write() => %d\n", (int)write_count));
811
812 return write_count;
813 }
814
815 /*
816 =item i_io_seek(io, offset, whence)
817 =category I/O Layers
818
819 Seek within the stream.
820
821 Acts like perl's seek.
822
823 =cut
824 */
825
826 off_t
827 i_io_seek(io_glue *ig, off_t offset, int whence) {
828 off_t new_off;
829
830 IOL_DEB(fprintf(IOL_DEBs, "i_io_seek(%p, %ld, %d)\n", ig, (long)offset, whence));
831
832 if (ig->write_ptr && ig->write_ptr != ig->write_end) {
833 if (!i_io_flush(ig))
834 return (off_t)(-1);
835 }
836
837 if (whence == SEEK_CUR && ig->read_ptr && ig->read_ptr != ig->read_end)
838 offset -= ig->read_end - ig->read_ptr;
839
840 ig->read_ptr = ig->read_end = NULL;
841 ig->write_ptr = ig->write_end = NULL;
842 ig->error = 0;
843 ig->buf_eof = 0;
844
845 new_off = i_io_raw_seek(ig, offset, whence);
846 if (new_off < 0)
847 ig->error = 1;
848
849 IOL_DEB(fprintf(IOL_DEBs, "i_io_seek() => %ld\n", (long)new_off));
850
851 return new_off;
852 }
853
854 /*
855 =item i_io_flush(io)
856 =category I/O Layers
857
858 Flush any buffered output.
859
860 Returns true on success,
861
862 =cut
863 */
864
865 int
866 i_io_flush(io_glue *ig) {
867 unsigned char *bufp;
868
869 IOL_DEB(fprintf(IOL_DEBs, "i_io_flush(%p)\n", ig));
870
871 if (ig->error) {
872 IOL_DEB(fprintf(IOL_DEBs, "i_io_flush() => 0 (error set)\n", ig));
873 return 0;
874 }
875
876 /* nothing to do */
877 if (!ig->write_ptr)
878 return 1;
879
880 bufp = ig->buffer;
881 while (bufp < ig->write_ptr) {
882 ssize_t rc = i_io_raw_write(ig, bufp, ig->write_ptr - bufp);
883 if (rc <= 0) {
884 IOL_DEB(fprintf(IOL_DEBs, "i_io_flush() => 0 (write error)\n", ig));
885 ig->error = 1;
886 return 0;
887 }
888
889 bufp += rc;
890 }
891
892 ig->write_ptr = ig->write_end = NULL;
893
894 IOL_DEB(fprintf(IOL_DEBs, "i_io_flush() => 1\n", ig));
895
896 return 1;
897 }
898
899 /*
900 =item i_io_close(io)
901 =category I/O Layers
902
903 Flush any pending output and perform the close action for the stream.
904
905 Returns 0 on success.
906
907 =cut
908 */
909
910 int
911 i_io_close(io_glue *ig) {
912 int result = 0;
913
914 IOL_DEB(fprintf(IOL_DEBs, "i_io_close(%p)\n", ig));
915 if (ig->error)
916 result = -1;
917
918 if (ig->write_ptr && !i_io_flush(ig))
919 result = -1;
920
921 if (i_io_raw_close(ig))
922 result = -1;
923
924 IOL_DEB(fprintf(IOL_DEBs, "i_io_close() => %d\n", result));
925
926 return result;
927 }
928
929 /*
930 =item i_io_gets(ig, buffer, size, end_of_line)
931 =category I/O Layers
932 =synopsis char buffer[BUFSIZ]
933 =synopsis ssize_t len = i_io_gets(buffer, sizeof(buffer), '\n');
934
935 Read up to C<size>-1 bytes from the stream C<ig> into C<buffer>.
936
937 If the byte C<end_of_line> is seen then no further bytes will be read.
938
939 Returns the number of bytes read.
940
941 Always C<NUL> terminates the buffer.
942
943 =cut
944 */
945
946 ssize_t
947 i_io_gets(io_glue *ig, char *buffer, size_t size, int eol) {
948 ssize_t read_count = 0;
949 if (size < 2)
950 return 0;
951 --size; /* room for nul */
952 while (size > 0) {
953 int byte = i_io_getc(ig);
954 if (byte == EOF)
955 break;
956 *buffer++ = byte;
957 ++read_count;
958 if (byte == eol)
959 break;
960 --size;
961 }
962 *buffer++ = '\0';
963
964 return read_count;
965 }
966
967 /*
968 =item i_io_init(ig, readcb, writecb, seekcb)
969
970 Do common initialization for io_glue objects.
971
972 =cut
973 */
974
975 static void
976 i_io_init(io_glue *ig, int type, i_io_readp_t readcb, i_io_writep_t writecb,
977 i_io_seekp_t seekcb) {
978 ig->type = type;
979 ig->exdata = NULL;
980 ig->readcb = readcb;
981 ig->writecb = writecb;
982 ig->seekcb = seekcb;
983 ig->closecb = NULL;
984 ig->sizecb = NULL;
985 ig->destroycb = NULL;
986
987 ig->buffer = NULL;
988 ig->read_ptr = NULL;
989 ig->read_end = NULL;
990 ig->write_ptr = NULL;
991 ig->write_end = NULL;
992 ig->buf_size = IO_BUF_SIZE;
993 ig->buf_eof = 0;
994 ig->error = 0;
995 ig->buffered = 1;
996 }
997
998 /*
999 =item i_io_set_buffered(io, buffered)
1000 =category I/O Layers
1001
1002 Set the buffering mode of the stream.
1003
1004 If you switch buffering off on a stream with buffering on:
1005
1006 =over
1007
1008 =item *
1009
1010 any buffered output will be flushed.
1011
1012 =item *
1013
1014 any existing buffered input will be consumed before reads become
1015 unbuffered.
1016
1017 =back
1018
1019 Returns true on success. This may fail if any buffered output cannot
1020 be flushed.
1021
1022 =cut
1023 */
1024
1025 int
1026 i_io_set_buffered(io_glue *ig, int buffered) {
1027 if (!buffered && ig->write_ptr) {
1028 if (!i_io_flush(ig)) {
1029 ig->error = 1;
1030 return 0;
1031 }
1032 }
1033 ig->buffered = buffered;
1034
1035 return 1;
1036 }
1037
1038 /*
1039 =item i_io_dump(ig)
1040
1041 Dump the base fields of an io_glue object to stdout.
1042
1043 =cut
1044 */
1045 void
1046 i_io_dump(io_glue *ig, int flags) {
1047 fprintf(IOL_DEBs, "ig %p:\n", ig);
1048 fprintf(IOL_DEBs, " type: %d\n", ig->type);
1049 fprintf(IOL_DEBs, " exdata: %p\n", ig->exdata);
1050 if (flags & I_IO_DUMP_CALLBACKS) {
1051 fprintf(IOL_DEBs, " readcb: %p\n", ig->readcb);
1052 fprintf(IOL_DEBs, " writecb: %p\n", ig->writecb);
1053 fprintf(IOL_DEBs, " seekcb: %p\n", ig->seekcb);
1054 fprintf(IOL_DEBs, " closecb: %p\n", ig->closecb);
1055 fprintf(IOL_DEBs, " sizecb: %p\n", ig->sizecb);
1056 }
1057 if (flags & I_IO_DUMP_BUFFER) {
1058 fprintf(IOL_DEBs, " buffer: %p\n", ig->buffer);
1059 fprintf(IOL_DEBs, " read_ptr: %p\n", ig->read_ptr);
1060 if (ig->read_ptr) {
1061 fprintf(IOL_DEBs, " ");
1062 dump_data(ig->read_ptr, ig->read_end, 0);
1063 putc('\n', IOL_DEBs);
1064 }
1065 fprintf(IOL_DEBs, " read_end: %p\n", ig->read_end);
1066 fprintf(IOL_DEBs, " write_ptr: %p\n", ig->write_ptr);
1067 if (ig->write_ptr) {
1068 fprintf(IOL_DEBs, " ");
1069 dump_data(ig->buffer, ig->write_ptr, 1);
1070 putc('\n', IOL_DEBs);
1071 }
1072 fprintf(IOL_DEBs, " write_end: %p\n", ig->write_end);
1073 fprintf(IOL_DEBs, " buf_size: %u\n", (unsigned)(ig->buf_size));
1074 }
1075 if (flags & I_IO_DUMP_STATUS) {
1076 fprintf(IOL_DEBs, " buf_eof: %d\n", ig->buf_eof);
1077 fprintf(IOL_DEBs, " error: %d\n", ig->error);
1078 fprintf(IOL_DEBs, " buffered: %d\n", ig->buffered);
1079 }
1080 }
1081
1082 /*
1083 =back
1084
1085 =head1 INTERNAL FUNCTIONS
1086
1087 =over
1088
1089 =item my_strerror
1090
1091 Calls strerror() and ensures we don't return NULL.
1092
1093 On some platforms it's possible for strerror() to return NULL, this
1094 wrapper ensures we only get non-NULL values.
1095
1096 =cut
1097 */
1098
1099 static
1100 const char *my_strerror(int err) {
1101 const char *result = strerror(err);
1102
1103 if (!result)
1104 result = "Unknown error";
1105
1106 return result;
1107 }
1108
1109 static void
1110 i_io_setup_buffer(io_glue *ig) {
1111 ig->buffer = mymalloc(ig->buf_size);
1112 }
1113
1114 static void
1115 i_io_start_write(io_glue *ig) {
1116 ig->write_ptr = ig->buffer;
1117 ig->write_end = ig->buffer + ig->buf_size;
1118 }
1119
1120 static int
1121 i_io_read_fill(io_glue *ig, ssize_t needed) {
1122 unsigned char *buf_end = ig->buffer + ig->buf_size;
1123 unsigned char *buf_start = ig->buffer;
1124 unsigned char *work = ig->buffer;
1125 ssize_t rc;
1126 int good = 0;
1127
1128 IOL_DEB(fprintf(IOL_DEBs, "i_io_read_fill(%p, %d)\n", ig, (int)needed));
1129
1130 /* these conditions may be unused, callers should also be checking them */
1131 if (ig->error || ig->buf_eof)
1132 return 0;
1133
1134 if (needed > ig->buf_size)
1135 needed = ig->buf_size;
1136
1137 if (ig->read_ptr && ig->read_ptr < ig->read_end) {
1138 size_t kept = ig->read_end - ig->read_ptr;
1139
1140 if (needed < kept) {
1141 IOL_DEB(fprintf(IOL_DEBs, "i_io_read_fill(%u) -> 1 (already have enough)\n", (unsigned)needed));
1142 return 1;
1143 }
1144
1145 if (ig->read_ptr != ig->buffer)
1146 memmove(ig->buffer, ig->read_ptr, kept);
1147
1148 good = 1; /* we have *something* available to read */
1149 work = buf_start + kept;
1150 needed -= kept;
1151 }
1152 else {
1153 work = ig->buffer;
1154 }
1155
1156 while (work < buf_end && (rc = i_io_raw_read(ig, work, buf_end - work)) > 0) {
1157 work += rc;
1158 good = 1;
1159 if (needed < rc)
1160 break;
1161
1162 needed -= rc;
1163 }
1164
1165 if (rc < 0) {
1166 ig->error = 1;
1167 IOL_DEB(fprintf(IOL_DEBs, " i_io_read_fill -> rc %d, setting error\n",
1168 (int)rc));
1169 }
1170 else if (rc == 0) {
1171 ig->buf_eof = 1;
1172 IOL_DEB(fprintf(IOL_DEBs, " i_io_read_fill -> rc 0, setting eof\n"));
1173 }
1174
1175 if (good) {
1176 ig->read_ptr = buf_start;
1177 ig->read_end = work;
1178 }
1179
1180 IOL_DEB(fprintf(IOL_DEBs, "i_io_read_fill => %d, %u buffered\n", good,
1181 (unsigned)(ig->read_end - ig->read_ptr)));
1182 return good;
1183 }
1184
1185 /*
1186 =item dump_data(start, end, bias)
1187
1188 Hex dump the data between C<start> and C<end>.
1189
1190 If there is more than a pleasing amount of data, either dump the
1191 beginning (C<bias == 0>) or dump the end C(<bias != 0>) of the range.
1192
1193 =cut
1194 */
1195
1196 static void
1197 dump_data(unsigned char *start, unsigned char *end, int bias) {
1198 unsigned char *p;
1199 size_t count = end - start;
1200
1201 if (start == end) {
1202 fprintf(IOL_DEBs, "(empty)");
1203 return;
1204 }
1205
1206 if (count > 15) {
1207 if (bias) {
1208 fprintf(IOL_DEBs, "... ");
1209 start = end - 14;
1210 }
1211 else {
1212 end = start + 14;
1213 }
1214
1215 for (p = start; p < end; ++p) {
1216 fprintf(IOL_DEBs, " %02x", *p);
1217 }
1218 putc(' ', IOL_DEBs);
1219 putc('<', IOL_DEBs);
1220 for (p = start; p < end; ++p) {
1221 if (*p < ' ' || *p > '~')
1222 putc('.', IOL_DEBs);
1223 else
1224 putc(*p, IOL_DEBs);
1225 }
1226 putc('>', IOL_DEBs);
1227 if (!bias)
1228 fprintf(IOL_DEBs, " ...");
1229 }
1230 else {
1231 for (p = start; p < end; ++p) {
1232 fprintf(IOL_DEBs, " %02x", *p);
1233 }
1234 putc(' ', IOL_DEBs);
1235 for (p = start; p < end; ++p) {
1236 if (*p < ' ' || *p > '~')
1237 putc('.', IOL_DEBs);
1238 else
1239 putc(*p, IOL_DEBs);
1240 }
1241 }
1242 }
1191243
1201244 /*
1211245 * Callbacks for sources that cannot seek
1221246 */
123
124 /* fakeseek_read: read method for when emulating a seekable source
125 static
126 ssize_t
127 fakeseek_read(io_glue *ig, void *buf, size_t count) {
128 io_ex_fseek *exdata = ig->exdata;
129 return 0;
130 }
131 */
132
133
1341247
1351248 /*
1361249 * Callbacks for sources that can seek
1501263
1511264 static
1521265 ssize_t
153 realseek_read(io_glue *ig, void *buf, size_t count) {
154 io_ex_rseek *ier = ig->exdata;
155 void *p = ig->source.cb.p;
1266 realseek_read(io_glue *igo, void *buf, size_t count) {
1267 io_cb *ig = (io_cb *)igo;
1268 void *p = ig->p;
1561269 ssize_t rc = 0;
157 size_t bc = 0;
158 char *cbuf = buf;
159
160 IOL_DEB( printf("realseek_read: buf = %p, count = %d\n",
161 buf, count) );
162 /* Is this a good idea? Would it be better to handle differently?
163 skip handling? */
164 while( count!=bc && (rc = ig->source.cb.readcb(p,cbuf+bc,count-bc))>0 ) {
165 bc+=rc;
166 }
167
168 ier->cpos += bc;
169 IOL_DEB( printf("realseek_read: rc = %d, bc = %d\n", rc, bc) );
170 return rc < 0 ? rc : bc;
1270
1271 IOL_DEB( fprintf(IOL_DEBs, "realseek_read: buf = %p, count = %u\n",
1272 buf, (unsigned)count) );
1273 rc = ig->readcb(p,buf,count);
1274
1275 IOL_DEB( fprintf(IOL_DEBs, "realseek_read: rc = %d\n", (int)rc) );
1276
1277 return rc;
1711278 }
1721279
1731280
1851292
1861293 static
1871294 ssize_t
188 realseek_write(io_glue *ig, const void *buf, size_t count) {
189 io_ex_rseek *ier = ig->exdata;
190 void *p = ig->source.cb.p;
1295 realseek_write(io_glue *igo, const void *buf, size_t count) {
1296 io_cb *ig = (io_cb *)igo;
1297 void *p = ig->p;
1911298 ssize_t rc = 0;
1921299 size_t bc = 0;
1931300 char *cbuf = (char*)buf;
1941301
195 IOL_DEB( printf("realseek_write: ig = %p, ier->cpos = %ld, buf = %p, "
196 "count = %d\n", ig, (long) ier->cpos, buf, count) );
1302 IOL_DEB( fprintf(IOL_DEBs, "realseek_write: ig = %p, buf = %p, "
1303 "count = %u\n", ig, buf, (unsigned)count) );
1971304
1981305 /* Is this a good idea? Would it be better to handle differently?
1991306 skip handling? */
200 while( count!=bc && (rc = ig->source.cb.writecb(p,cbuf+bc,count-bc))>0 ) {
1307 while( count!=bc && (rc = ig->writecb(p,cbuf+bc,count-bc))>0 ) {
2011308 bc+=rc;
2021309 }
2031310
204 ier->cpos += bc;
205 IOL_DEB( printf("realseek_write: rc = %d, bc = %d\n", rc, bc) );
1311 IOL_DEB( fprintf(IOL_DEBs, "realseek_write: rc = %d, bc = %u\n", (int)rc, (unsigned)bc) );
2061312 return rc < 0 ? rc : bc;
2071313 }
2081314
2191325
2201326 static
2211327 int
222 realseek_close(io_glue *ig) {
1328 realseek_close(io_glue *igo) {
1329 io_cb *ig = (io_cb *)igo;
1330
1331 IOL_DEB(fprintf(IOL_DEBs, "realseek_close(%p)\n", ig));
2231332 mm_log((1, "realseek_close(ig %p)\n", ig));
224 if (ig->source.cb.closecb)
225 return ig->source.cb.closecb(ig->source.cb.p);
1333 if (ig->closecb)
1334 return ig->closecb(ig->p);
2261335 else
2271336 return 0;
2281337 }
2421351
2431352 static
2441353 off_t
245 realseek_seek(io_glue *ig, off_t offset, int whence) {
246 /* io_ex_rseek *ier = ig->exdata; Needed later */
247 void *p = ig->source.cb.p;
1354 realseek_seek(io_glue *igo, off_t offset, int whence) {
1355 io_cb *ig = (io_cb *)igo;
1356 void *p = ig->p;
2481357 off_t rc;
249 IOL_DEB( printf("realseek_seek(ig %p, offset %ld, whence %d)\n", ig, (long) offset, whence) );
250 rc = ig->source.cb.seekcb(p, offset, whence);
251
252 IOL_DEB( printf("realseek_seek: rc %ld\n", (long) rc) );
1358 IOL_DEB( fprintf(IOL_DEBs, "realseek_seek(ig %p, offset %ld, whence %d)\n", ig, (long) offset, whence) );
1359 rc = ig->seekcb(p, offset, whence);
1360
1361 IOL_DEB( fprintf(IOL_DEBs, "realseek_seek: rc %ld\n", (long) rc) );
2531362 return rc;
2541363 /* FIXME: How about implementing this offset handling stuff? */
2551364 }
2561365
2571366 static
2581367 void
259 realseek_destroy(io_glue *ig) {
260 io_ex_rseek *ier = ig->exdata;
261
262 if (ig->source.cb.destroycb)
263 ig->source.cb.destroycb(ig->source.cb.p);
264
265 myfree(ier);
1368 realseek_destroy(io_glue *igo) {
1369 io_cb *ig = (io_cb *)igo;
1370
1371 if (ig->destroycb)
1372 ig->destroycb(ig->p);
2661373 }
2671374
2681375 /*
2831390
2841391 static
2851392 ssize_t
286 buffer_read(io_glue *ig, void *buf, size_t count) {
287 io_ex_buffer *ieb = ig->exdata;
288
289 IOL_DEB( printf("buffer_read: ieb->cpos = %ld, buf = %p, count = %d\n", (long) ieb->cpos, buf, count) );
290
291 if ( ieb->cpos+count > ig->source.buffer.len ) {
292 mm_log((1,"buffer_read: short read: cpos=%ld, len=%ld, count=%ld\n", (long)ieb->cpos, (long)ig->source.buffer.len, (long)count));
293 count = ig->source.buffer.len - ieb->cpos;
294 }
295
296 memcpy(buf, ig->source.buffer.data+ieb->cpos, count);
297 ieb->cpos += count;
298 IOL_DEB( printf("buffer_read: count = %ld\n", (long)count) );
1393 buffer_read(io_glue *igo, void *buf, size_t count) {
1394 io_buffer *ig = (io_buffer *)igo;
1395
1396 IOL_DEB( fprintf(IOL_DEBs, "buffer_read: ig->cpos = %ld, buf = %p, count = %u\n", (long) ig->cpos, buf, (unsigned)count) );
1397
1398 if ( ig->cpos+count > ig->len ) {
1399 mm_log((1,"buffer_read: short read: cpos=%ld, len=%ld, count=%ld\n", (long)ig->cpos, (long)ig->len, (long)count));
1400 count = ig->len - ig->cpos;
1401 }
1402
1403 memcpy(buf, ig->data+ig->cpos, count);
1404 ig->cpos += count;
1405 IOL_DEB( fprintf(IOL_DEBs, "buffer_read: count = %ld\n", (long)count) );
2991406 return count;
3001407 }
3011408
3531460
3541461 static
3551462 off_t
356 buffer_seek(io_glue *ig, off_t offset, int whence) {
357 io_ex_buffer *ieb = ig->exdata;
1463 buffer_seek(io_glue *igo, off_t offset, int whence) {
1464 io_buffer *ig = (io_buffer *)igo;
3581465 off_t reqpos =
359 calc_seek_offset(ieb->cpos, ig->source.buffer.len, offset, whence);
360
361 if (reqpos > ig->source.buffer.len) {
1466 calc_seek_offset(ig->cpos, ig->len, offset, whence);
1467
1468 if (reqpos > ig->len) {
3621469 mm_log((1, "seeking out of readable range\n"));
3631470 return (off_t)-1;
3641471 }
3671474 return (off_t)-1;
3681475 }
3691476
370 ieb->cpos = reqpos;
371 IOL_DEB( printf("buffer_seek(ig %p, offset %ld, whence %d)\n", ig, (long) offset, whence) );
1477 ig->cpos = reqpos;
1478 IOL_DEB( fprintf(IOL_DEBs, "buffer_seek(ig %p, offset %ld, whence %d)\n", ig, (long) offset, whence) );
3721479
3731480 return reqpos;
3741481 /* FIXME: How about implementing this offset handling stuff? */
3761483
3771484 static
3781485 void
379 buffer_destroy(io_glue *ig) {
380 io_ex_buffer *ieb = ig->exdata;
381
382 if (ig->source.buffer.closecb) {
1486 buffer_destroy(io_glue *igo) {
1487 io_buffer *ig = (io_buffer *)igo;
1488
1489 if (ig->closecb) {
3831490 mm_log((1,"calling close callback %p for io_buffer\n",
384 ig->source.buffer.closecb));
385 ig->source.buffer.closecb(ig->source.buffer.closedata);
386 }
387 myfree(ieb);
1491 ig->closecb));
1492 ig->closecb(ig->closedata);
1493 }
3881494 }
3891495
3901496
4511557 =cut
4521558 */
4531559
454 void
1560 static void
4551561 io_destroy_bufchain(io_ex_bchain *ieb) {
4561562 io_blink *cp;
4571563 mm_log((1, "io_destroy_bufchain(ieb %p)\n", ieb));
5661672 }
5671673 */
5681674
569
570
571
572
573
574
575
576
577
578
5791675 /*
5801676 =item bufchain_read(ig, buf, count)
5811677
6461742
6471743 mm_log((1, "bufchain_write: ig = %p, buf = %p, count = %ld\n", ig, buf, (long)count));
6481744
649 IOL_DEB( printf("bufchain_write: ig = %p, ieb->cpos = %ld, buf = %p, count = %ld\n", ig, (long) ieb->cpos, buf, (long)count) );
1745 IOL_DEB( fprintf(IOL_DEBs, "bufchain_write: ig = %p, ieb->cpos = %ld, buf = %p, count = %ld\n", ig, (long) ieb->cpos, buf, (long)count) );
6501746
6511747 while(count) {
6521748 mm_log((2, "bufchain_write: - looping - count = %ld\n", (long)count));
6901786 int
6911787 bufchain_close(io_glue *ig) {
6921788 mm_log((1, "bufchain_close(ig %p)\n",ig));
693 IOL_DEB( printf("bufchain_close(ig %p)\n", ig) );
1789 IOL_DEB( fprintf(IOL_DEBs, "bufchain_close(ig %p)\n", ig) );
6941790
6951791 return 0;
6961792 }
7811877 }
7821878
7831879 /*
784 * Methods for setting up data source
785 */
786
787 /*
788 =item io_obj_setp_buffer(io, p, len)
789
790 Sets an io_object for reading from a buffer source
791
792 io - io object that describes a source
793 p - pointer to buffer
794 len - length of buffer
795
796 =cut
797 */
798
799 static void
800 io_obj_setp_buffer(io_obj *io, char *p, size_t len, i_io_closebufp_t closecb,
801 void *closedata) {
802 io->buffer.type = BUFFER;
803 io->buffer.data = p;
804 io->buffer.len = len;
805 io->buffer.closecb = closecb;
806 io->buffer.closedata = closedata;
807 }
808
809
810
811 /*
812 =item io_obj_setp_cb2(io, p, readcb, writecb, seekcb, closecb, destroycb)
813
814 Sets an io_object for reading from a source that uses callbacks
815
816 io - io object that describes a source
817 p - pointer to data for callbacks
818 readcb - read callback to read from source
819 writecb - write callback to write to source
820 seekcb - seek callback to seek on source
821 closecb - flush any pending data
822 destroycb - release any extra resources
823
824 =cut
825 */
826
827 static void
828 io_obj_setp_cb2(io_obj *io, void *p, i_io_readl_t readcb, i_io_writel_t writecb, i_io_seekl_t seekcb, i_io_closel_t closecb, i_io_destroyl_t destroycb) {
829 io->cb.type = CBSEEK;
830 io->cb.p = p;
831 io->cb.readcb = readcb;
832 io->cb.writecb = writecb;
833 io->cb.seekcb = seekcb;
834 io->cb.closecb = closecb;
835 io->cb.destroycb = destroycb;
836 }
837
838 /*
839 =item io_glue_commit_types(ig)
840
841 This is now effectively a no-op.
842
843 =cut
844 */
845
846 void
847 io_glue_commit_types(io_glue *ig) {
848 io_type inn = ig->source.type;
849
850 mm_log((1, "io_glue_commit_types(ig %p)\n", ig));
851 mm_log((1, "io_glue_commit_types: source type %d (%s)\n", inn, io_type_names[inn]));
852
853 if (ig->flags & 0x01) {
854 mm_log((1, "io_glue_commit_types: type already set up\n"));
855 return;
856 }
857
858 ig->flags |= 0x01; /* indicate source has been setup already */
859 }
860
861 /*
862 =item io_glue_gettypes(ig, reqmeth)
863
864 Returns a set of compatible interfaces to read data with.
865
866 ig - io_glue object
867 reqmeth - request mask
868
869 The request mask is a bit mask (of something that hasn't been implemented yet)
870 of interfaces that it would like to read data from the source which the ig
871 describes.
872
873 =cut
874 */
875
876 void
877 io_glue_gettypes(io_glue *ig, int reqmeth) {
878
879 ig = NULL;
880 reqmeth = 0;
881
882 /* FIXME: Implement this function! */
883 /* if (ig->source.type =
884 if (reqmeth & IO_BUFF) */
885
886 }
887
888
889 /*
890 =item io_new_bufchain()
891
892 returns a new io_glue object that has the 'empty' source and but can
893 be written to and read from later (like a pseudo file).
894
895 =cut
896 */
897
898 io_glue *
899 io_new_bufchain() {
900 io_glue *ig;
901 io_ex_bchain *ieb = mymalloc(sizeof(io_ex_bchain));
902
903 mm_log((1, "io_new_bufchain()\n"));
904
905 ig = mymalloc(sizeof(io_glue));
906 memset(ig, 0, sizeof(*ig));
907 ig->source.type = BUFCHAIN;
908
909 ieb->offset = 0;
910 ieb->length = 0;
911 ieb->cpos = 0;
912 ieb->gpos = 0;
913 ieb->tfill = 0;
914
915 ieb->head = io_blink_new();
916 ieb->cp = ieb->head;
917 ieb->tail = ieb->head;
918
919 ig->exdata = ieb;
920 ig->readcb = bufchain_read;
921 ig->writecb = bufchain_write;
922 ig->seekcb = bufchain_seek;
923 ig->closecb = bufchain_close;
924 ig->destroycb = bufchain_destroy;
925
926 return ig;
927 }
928
929 /*
930 =item io_new_buffer(data, len)
931
932 Returns a new io_glue object that has the source defined as reading
933 from specified buffer. Note that the buffer is not copied.
934
935 data - buffer to read from
936 len - length of buffer
937
938 =cut
939 */
940
941 io_glue *
942 io_new_buffer(char *data, size_t len, i_io_closebufp_t closecb, void *closedata) {
943 io_glue *ig;
944 io_ex_buffer *ieb = mymalloc(sizeof(io_ex_buffer));
945
946 mm_log((1, "io_new_buffer(data %p, len %ld, closecb %p, closedata %p)\n", data, (long)len, closecb, closedata));
947
948 ig = mymalloc(sizeof(io_glue));
949 memset(ig, 0, sizeof(*ig));
950 io_obj_setp_buffer(&ig->source, data, len, closecb, closedata);
951 ig->flags = 0;
952
953 ieb->offset = 0;
954 ieb->cpos = 0;
955
956 ig->exdata = ieb;
957 ig->readcb = buffer_read;
958 ig->writecb = buffer_write;
959 ig->seekcb = buffer_seek;
960 ig->closecb = buffer_close;
961 ig->destroycb = buffer_destroy;
962
963 return ig;
964 }
965
966
967 /*
968 =item io_new_fd(fd)
969
970 returns a new io_glue object that has the source defined as reading
971 from specified filedescriptor. Note that the the interface to recieving
972 data from the io_glue callbacks hasn't been done yet.
973
974 fd - file descriptor to read/write from
975
976 =cut
977 */
978
979 io_glue *
980 io_new_fd(int fd) {
981 io_glue *ig;
982
983 mm_log((1, "io_new_fd(fd %d)\n", fd));
984
985 ig = mymalloc(sizeof(io_glue));
986 memset(ig, 0, sizeof(*ig));
987 ig->source.type = FDSEEK;
988 ig->source.fdseek.fd = fd;
989 ig->flags = 0;
990
991 ig->exdata = NULL;
992 ig->readcb = fd_read;
993 ig->writecb = fd_write;
994 ig->seekcb = fd_seek;
995 ig->closecb = fd_close;
996 ig->sizecb = fd_size;
997 ig->destroycb = NULL;
998
999 mm_log((1, "(%p) <- io_new_fd\n", ig));
1000 return ig;
1001 }
1002
1003 io_glue *io_new_cb(void *p, i_io_readl_t readcb, i_io_writel_t writecb,
1004 i_io_seekl_t seekcb, i_io_closel_t closecb,
1005 i_io_destroyl_t destroycb) {
1006 io_glue *ig;
1007 io_ex_rseek *ier = mymalloc(sizeof(io_ex_rseek));
1008
1009 mm_log((1, "io_new_cb(p %p, readcb %p, writecb %p, seekcb %p, closecb %p, "
1010 "destroycb %p)\n", p, readcb, writecb, seekcb, closecb, destroycb));
1011 ig = mymalloc(sizeof(io_glue));
1012 memset(ig, 0, sizeof(*ig));
1013 io_obj_setp_cb2(&ig->source, p, readcb, writecb, seekcb, closecb, destroycb);
1014 mm_log((1, "(%p) <- io_new_cb\n", ig));
1015
1016 ier->offset = 0;
1017 ier->cpos = 0;
1018
1019 ig->exdata = ier;
1020 ig->readcb = realseek_read;
1021 ig->writecb = realseek_write;
1022 ig->seekcb = realseek_seek;
1023 ig->closecb = realseek_close;
1024 ig->destroycb = realseek_destroy;
1025
1026 return ig;
1027 }
1028
1029 /*
1030 =item io_slurp(ig)
1031
1032 Takes the source that the io_glue is bound to and allocates space
1033 for a return buffer and returns the entire content in a single buffer.
1034 Note: This only works for io_glue objects that contain a bufchain. It
1035 is usefull for saving to scalars and such.
1036
1037 ig - io_glue object
1038 c - pointer to a pointer to where data should be copied to
1039
1040 =cut
1041 */
1042
1043 size_t
1044 io_slurp(io_glue *ig, unsigned char **c) {
1045 ssize_t rc;
1046 off_t orgoff;
1047 io_ex_bchain *ieb;
1048 unsigned char *cc;
1049 io_type inn = ig->source.type;
1050
1051 if ( inn != BUFCHAIN ) {
1052 i_fatal(0, "io_slurp: called on a source that is not from a bufchain\n");
1053 }
1054
1055 ieb = ig->exdata;
1056 cc = *c = mymalloc( ieb->length );
1057
1058 orgoff = ieb->gpos;
1059
1060 bufchain_seek(ig, 0, SEEK_SET);
1061
1062 rc = bufchain_read(ig, cc, ieb->length);
1063
1064 if (rc != ieb->length)
1065 i_fatal(1, "io_slurp: bufchain_read returned an incomplete read: rc = %d, request was %d\n", rc, ieb->length);
1066
1067 return rc;
1068 }
1069
1070 /*
10711880 =item fd_read(ig, buf, count)
10721881
1073 =cut
1074 */
1075 static ssize_t fd_read(io_glue *ig, void *buf, size_t count) {
1882 Read callback for file descriptor IO objects.
1883
1884 =cut
1885 */
1886 static ssize_t fd_read(io_glue *igo, void *buf, size_t count) {
1887 io_fdseek *ig = (io_fdseek *)igo;
10761888 ssize_t result;
10771889 #ifdef _MSC_VER
1078 result = _read(ig->source.fdseek.fd, buf, count);
1890 result = _read(ig->fd, buf, count);
10791891 #else
1080 result = read(ig->source.fdseek.fd, buf, count);
1892 result = read(ig->fd, buf, count);
10811893 #endif
1894
1895 IOL_DEB(fprintf(IOL_DEBs, "fd_read(%p, %p, %u) => %d\n", ig, buf,
1896 (unsigned)count, (int)result));
10821897
10831898 /* 0 is valid - means EOF */
10841899 if (result < 0) {
10881903 return result;
10891904 }
10901905
1091 static ssize_t fd_write(io_glue *ig, const void *buf, size_t count) {
1906 static ssize_t fd_write(io_glue *igo, const void *buf, size_t count) {
1907 io_fdseek *ig = (io_fdseek *)igo;
10921908 ssize_t result;
10931909 #ifdef _MSC_VER
1094 result = _write(ig->source.fdseek.fd, buf, count);
1910 result = _write(ig->fd, buf, count);
10951911 #else
1096 result = write(ig->source.fdseek.fd, buf, count);
1912 result = write(ig->fd, buf, count);
10971913 #endif
1914
1915 IOL_DEB(fprintf(IOL_DEBs, "fd_write(%p, %p, %u) => %d\n", ig, buf,
1916 (unsigned)count, (int)result));
10981917
10991918 if (result <= 0) {
11001919 i_push_errorf(errno, "write() failure: %s (%d)", my_strerror(errno), errno);
11031922 return result;
11041923 }
11051924
1106 static off_t fd_seek(io_glue *ig, off_t offset, int whence) {
1925 static off_t fd_seek(io_glue *igo, off_t offset, int whence) {
1926 io_fdseek *ig = (io_fdseek *)igo;
11071927 off_t result;
11081928 #ifdef _MSC_VER
1109 result = _lseek(ig->source.fdseek.fd, offset, whence);
1929 result = _lseek(ig->fd, offset, whence);
11101930 #else
1111 result = lseek(ig->source.fdseek.fd, offset, whence);
1931 result = lseek(ig->fd, offset, whence);
11121932 #endif
11131933
11141934 if (result == (off_t)-1) {
11291949 return -1;
11301950 }
11311951
1132 /*
1133 =item io_glue_destroy(ig)
1134
1135 A destructor method for io_glue objects. Should clean up all related buffers.
1136 Might leave us with a dangling pointer issue on some buffers.
1137
1138 ig - io_glue object to destroy.
1139
1140 =cut
1141 */
1142
1143 void
1144 io_glue_destroy(io_glue *ig) {
1145 mm_log((1, "io_glue_DESTROY(ig %p)\n", ig));
1146
1147 if (ig->destroycb)
1148 ig->destroycb(ig);
1149
1150 myfree(ig);
1151 }
11521952
11531953 /*
11541954 =back
11551955
1156 =head1 INTERNAL FUNCTIONS
1157
1158 =over
1159
1160 =item my_strerror
1161
1162 Calls strerror() and ensures we don't return NULL.
1163
1164 On some platforms it's possible for strerror() to return NULL, this
1165 wrapper ensures we only get non-NULL values.
1166
1167 =cut
1168 */
1169
1170 static
1171 const char *my_strerror(int err) {
1172 const char *result = strerror(err);
1173
1174 if (!result)
1175 result = "Unknown error";
1176
1177 return result;
1178 }
1179
1180 /*
1181 =back
1182
11831956 =head1 AUTHOR
11841957
11851958 Arnar M. Hrafnkelsson <addi@umich.edu>
33
44 /* How the IO layer works:
55 *
6 * Start by getting an io_glue object. Then define its
7 * datasource via io_obj_setp_buffer or io_obj_setp_cb. Before
8 * using the io_glue object be sure to call io_glue_commit_types().
9 * After that data can be read via the io_glue->readcb() method.
6 * Start by getting an io_glue object by calling the appropriate
7 * io_new...() function. After that data can be read via the
8 * io_glue->readcb() method.
109 *
1110 */
1211
1918 #define IO_TEMP_SEEK 1<<1L
2019
2120
22 void io_glue_commit_types(io_glue *ig);
2321 void io_glue_gettypes (io_glue *ig, int reqmeth);
2422
2523 /* XS functions */
2624 io_glue *io_new_fd(int fd);
2725 io_glue *io_new_bufchain(void);
28 io_glue *io_new_buffer(char *data, size_t len, i_io_closebufp_t closecb, void *closedata);
26 io_glue *io_new_buffer(const char *data, size_t len, i_io_closebufp_t closecb, void *closedata);
2927 io_glue *io_new_cb(void *p, i_io_readl_t readcb, i_io_writel_t writecb, i_io_seekl_t seekcb, i_io_closel_t closecb, i_io_destroyl_t destroycb);
3028 size_t io_slurp(io_glue *ig, unsigned char **c);
3129 void io_glue_destroy(io_glue *ig);
3230
31 void i_io_dump(io_glue *ig, int flags);
32
33 /* Buffered I/O */
34 extern int i_io_getc_imp(io_glue *ig);
35 extern int i_io_peekc_imp(io_glue *ig);
36 extern ssize_t i_io_peekn(io_glue *ig, void *buf, size_t size);
37 extern int i_io_putc_imp(io_glue *ig, int c);
38 extern ssize_t i_io_read(io_glue *ig, void *buf, size_t size);
39 extern ssize_t i_io_write(io_glue *ig, const void *buf, size_t size);
40 extern off_t i_io_seek(io_glue *ig, off_t offset, int whence);
41 extern int i_io_flush(io_glue *ig);
42 extern int i_io_close(io_glue *ig);
43 extern int i_io_set_buffered(io_glue *ig, int buffered);
44 extern ssize_t i_io_gets(io_glue *ig, char *, size_t, int);
45
3346 #endif /* _IOLAYER_H_ */
4545
4646 /* Structures to describe data sources */
4747
48 typedef struct {
49 io_type type;
50 int fd;
51 } io_fdseek;
52
53 typedef struct {
54 io_type type; /* Must be first parameter */
55 char *name; /* Data source name */
56 char *data;
57 size_t len;
58 i_io_closebufp_t closecb; /* free memory mapped segment or decrement refcount */
59 void *closedata;
60 } io_buffer;
61
62 typedef struct {
63 io_type type; /* Must be first parameter */
64 char *name; /* Data source name */
65 void *p; /* Callback data */
66 i_io_readl_t readcb;
67 i_io_writel_t writecb;
68 i_io_seekl_t seekcb;
69 i_io_closel_t closecb;
70 i_io_destroyl_t destroycb;
71 } io_cb;
72
73 typedef union {
74 io_type type;
75 io_fdseek fdseek;
76 io_buffer buffer;
77 io_cb cb;
78 } io_obj;
79
8048 struct i_io_glue_t {
81 io_obj source;
82 int flags; /* Flags */
83 void *exdata; /* Pair specific data */
49 io_type type;
50 void *exdata;
8451 i_io_readp_t readcb;
8552 i_io_writep_t writecb;
8653 i_io_seekp_t seekcb;
8754 i_io_closep_t closecb;
8855 i_io_sizep_t sizecb;
8956 i_io_destroyp_t destroycb;
57 unsigned char *buffer;
58 unsigned char *read_ptr;
59 unsigned char *read_end;
60 unsigned char *write_ptr;
61 unsigned char *write_end;
62 size_t buf_size;
63
64 /* non-zero if we encountered EOF */
65 int buf_eof;
66
67 /* non-zero if we've seen an error */
68 int error;
69
70 /* if non-zero we do write buffering (enabled by default) */
71 int buffered;
9072 };
9173
74 #define I_IO_DUMP_CALLBACKS 1
75 #define I_IO_DUMP_BUFFER 2
76 #define I_IO_DUMP_STATUS 4
77 #define I_IO_DUMP_DEFAULT (I_IO_DUMP_BUFFER | I_IO_DUMP_STATUS)
78
9279 #define i_io_type(ig) ((ig)->source.ig_type)
93 #define i_io_read(ig, buf, size) ((ig)->readcb((ig), (buf), (size)))
94 #define i_io_write(ig, data, size) ((ig)->writecb((ig), (data), (size)))
95 #define i_io_seek(ig, offset, whence) ((ig)->seekcb((ig), (offset), (whence)))
96 #define i_io_close(ig) ((ig)->closecb(ig))
80 #define i_io_raw_read(ig, buf, size) ((ig)->readcb((ig), (buf), (size)))
81 #define i_io_raw_write(ig, data, size) ((ig)->writecb((ig), (data), (size)))
82 #define i_io_raw_seek(ig, offset, whence) ((ig)->seekcb((ig), (offset), (whence)))
83 #define i_io_raw_close(ig) ((ig)->closecb(ig))
84 #define i_io_is_buffered(ig) ((int)((ig)->buffered))
9785
86 #define i_io_getc(ig) \
87 ((ig)->read_ptr < (ig)->read_end ? \
88 *((ig)->read_ptr++) : \
89 i_io_getc_imp(ig))
90 #define i_io_peekc(ig) \
91 ((ig)->read_ptr < (ig)->read_end ? \
92 *((ig)->read_ptr) : \
93 i_io_peekc_imp(ig))
94 #define i_io_putc(ig, c) \
95 ((ig)->write_ptr < (ig)->write_end && !(ig)->error ? \
96 *(ig)->write_ptr++ = (c) : \
97 i_io_putc_imp(ig, (c)))
98 #define i_io_eof(ig) \
99 ((ig)->read_ptr == (ig)->read_end && (ig)->buf_eof)
100 #define i_io_error(ig) \
101 ((ig)->read_ptr == (ig)->read_end && (ig)->error)
98102
99103 #endif
5959 i_fr_triangle, 0, i_fts_grid, 9, 1, segs);
6060 i_fill_destroy(fill);
6161
62 # I/O Layers
63 ssize_t count = i_io_peekn(ig, buffer, sizeof(buffer));
64 ssize_t result = i_io_write(io, buffer, size)
65 char buffer[BUFSIZ]
66 ssize_t len = i_io_gets(buffer, sizeof(buffer), '\n');
67 io_glue_destroy(ig);
68
6269 # Image
6370
6471 # Image creation/destruction
65 i_img *img = i_img_8_new(width, height, channels);
6672 i_img *img = i_sametype(src, width, height);
6773 i_img *img = i_sametype_chans(src, width, height, channels);
74 i_img *img = i_img_16_new(width, height, channels);
75 i_img *img = i_img_8_new(width, height, channels);
76 i_img *img = i_img_double_new(width, height, channels);
6877 i_img *img = i_img_pal_new(width, height, channels, max_palette_size)
69 i_img *img = i_img_double_new(width, height, channels);
70 i_img *img = i_img_16_new(width, height, channels);
7178 i_img_destroy(img)
7279
7380 # Image Implementation
7481
7582 # Image Information
76 // only channel 0 writeable
83 // only channel 0 writable
7784 i_img_setmask(img, 0x01);
7885 int mask = i_img_getmask(img);
7986 int channels = i_img_getchannels(img);
10291036
10301037 =back
10311038
1039 =head2 I/O Layers
1040
1041 =over
1042
1043 =item io_new_bufchain()
1044
1045 returns a new io_glue object that has the 'empty' source and but can
1046 be written to and read from later (like a pseudo file).
1047
1048
1049 =for comment
1050 From: File iolayer.c
1051
1052 =item io_new_buffer(data, length)
1053
1054 Returns a new io_glue object that has the source defined as reading
1055 from specified buffer. Note that the buffer is not copied.
1056
1057 data - buffer to read from
1058 length - length of buffer
1059
1060
1061 =for comment
1062 From: File iolayer.c
1063
1064 =item io_new_cb(p, read_cb, write_cb, seek_cb, close_cb, destroy_cb)
1065
1066 Create a new I/O layer object that calls your supplied callbacks.
1067
1068 In general the callbacks should behave like the corresponding POSIX
1069 primitives.
1070
1071 =over
1072
1073 =item *
1074
1075 C<read_cb>(p, buffer, length) should read up to C<length> bytes into
1076 C<buffer> and return the number of bytes read. At end of file, return
1077 0. On error, return -1.
1078
1079 =item *
1080
1081 C<write_cb>(p, buffer, length) should write up to C<length> bytes from
1082 C<buffer> and return the number of bytes written. A return value <= 0
1083 will be treated as an error.
1084
1085 =item *
1086
1087 C<seekcb>(p, offset, whence) should seek and return the new offset.
1088
1089 =item *
1090
1091 C<close_cb>(p) should return 0 on success, -1 on failure.
1092
1093 =item *
1094
1095 C<destroy_cb>(p) should release any memory specific to your callback
1096 handlers.
1097
1098 =back
1099
1100
1101 =for comment
1102 From: File iolayer.c
1103
1104 =item io_new_fd(fd)
1105
1106 returns a new io_glue object that has the source defined as reading
1107 from specified file descriptor. Note that the the interface to receiving
1108 data from the io_glue callbacks hasn't been done yet.
1109
1110 fd - file descriptor to read/write from
1111
1112
1113 =for comment
1114 From: File iolayer.c
1115
1116 =item i_io_close(io)
1117
1118 Flush any pending output and perform the close action for the stream.
1119
1120 Returns 0 on success.
1121
1122
1123 =for comment
1124 From: File iolayer.c
1125
1126 =item i_io_flush(io)
1127
1128 Flush any buffered output.
1129
1130 Returns true on success,
1131
1132
1133 =for comment
1134 From: File iolayer.c
1135
1136 =item i_io_getc(ig)
1137
1138 A macro to read a single byte from a buffered I/O glue object.
1139
1140 Returns EOF on failure, or a byte.
1141
1142
1143 =for comment
1144 From: File iolayer.c
1145
1146 =item i_io_gets(ig, buffer, size, end_of_line)
1147
1148 char buffer[BUFSIZ]
1149 ssize_t len = i_io_gets(buffer, sizeof(buffer), '\n');
1150
1151 Read up to C<size>-1 bytes from the stream C<ig> into C<buffer>.
1152
1153 If the byte C<end_of_line> is seen then no further bytes will be read.
1154
1155 Returns the number of bytes read.
1156
1157 Always C<NUL> terminates the buffer.
1158
1159
1160 =for comment
1161 From: File iolayer.c
1162
1163 =item i_io_peekc(ig)
1164
1165 Read the next character from the stream without advancing the stream.
1166
1167 On error or end of file, return EOF.
1168
1169 For unbuffered streams a single character buffer will be setup.
1170
1171
1172 =for comment
1173 From: File iolayer.c
1174
1175 =item i_io_peekn(ig, buffer, size)
1176
1177 ssize_t count = i_io_peekn(ig, buffer, sizeof(buffer));
1178
1179 Buffer at least C<size> (at most C<< ig->buf_size >> bytes of data
1180 from the stream and return C<size> bytes of it to the caller in
1181 C<buffer>.
1182
1183 This ignores the buffered state of the stream, and will always setup
1184 buffering if needed.
1185
1186 If no C<type> parameter is provided to Imager::read() or
1187 Imager::read_multi(), Imager will call C<i_io_peekn()> when probing
1188 for the file format.
1189
1190 Returns -1 on error, 0 if there is no data before EOF, or the number
1191 of bytes read into C<buffer>.
1192
1193
1194 =for comment
1195 From: File iolayer.c
1196
1197 =item i_io_putc(ig, c)
1198
1199 Write a single character to the stream.
1200
1201 On success return c, on error returns EOF
1202
1203
1204 =for comment
1205 From: File iolayer.c
1206
1207 =item i_io_read(io, buffer, size)
1208
1209 Read up to C<size> bytes from the stream C<io> into C<buffer>.
1210
1211 Returns the number of bytes read. Returns 0 on end of file. Returns
1212 -1 on error.
1213
1214
1215 =for comment
1216 From: File iolayer.c
1217
1218 =item i_io_seek(io, offset, whence)
1219
1220 Seek within the stream.
1221
1222 Acts like perl's seek.
1223
1224
1225 =for comment
1226 From: File iolayer.c
1227
1228 =item i_io_set_buffered(io, buffered)
1229
1230 Set the buffering mode of the stream.
1231
1232 If you switch buffering off on a stream with buffering on:
1233
1234 =over
1235
1236 =item *
1237
1238 any buffered output will be flushed.
1239
1240 =item *
1241
1242 any existing buffered input will be consumed before reads become
1243 unbuffered.
1244
1245 =back
1246
1247 Returns true on success. This may fail if any buffered output cannot
1248 be flushed.
1249
1250
1251 =for comment
1252 From: File iolayer.c
1253
1254 =item i_io_write(io, buffer, size)
1255
1256 ssize_t result = i_io_write(io, buffer, size)
1257
1258 Write to the given I/O stream.
1259
1260 Returns the number of bytes written.
1261
1262
1263 =for comment
1264 From: File iolayer.c
1265
1266 =item io_slurp(ig, c)
1267
1268 Takes the source that the io_glue is bound to and allocates space for
1269 a return buffer and returns the entire content in a single buffer.
1270 Note: This only works for io_glue objects created by
1271 io_new_bufchain(). It is useful for saving to scalars and such.
1272
1273 ig - io_glue object
1274 c - pointer to a pointer to where data should be copied to
1275
1276 char *data;
1277 size_t size = io_slurp(ig, &data);
1278 ... do something with the data ...
1279 myfree(data);
1280
1281 io_slurp() will abort the program if the supplied I/O layer is not
1282 from io_new_bufchain().
1283
1284
1285 =for comment
1286 From: File iolayer.c
1287
1288 =item io_glue_destroy(ig)
1289
1290 io_glue_destroy(ig);
1291
1292 Destroy an io_glue objects. Should clean up all related buffers.
1293
1294 ig - io_glue object to destroy.
1295
1296
1297 =for comment
1298 From: File iolayer.c
1299
1300
1301 =back
1302
10321303 =head2 Image
10331304
10341305 =over
13431614
13441615 =item i_img_setmask(C<im>, C<ch_mask>)
13451616
1346 // only channel 0 writeable
1617 // only channel 0 writable
13471618 i_img_setmask(img, 0x01);
13481619
13491620 Set the image channel mask for C<im> to C<ch_mask>.
7272
7373 =over
7474
75 =item read
75 =item read()
7676
7777 Reading writing to and from files is simple, use the C<read()>
7878 method to read an image:
8787 $img->read(file => $filename)
8888 or die "Cannot read $filename: ", $img->errstr;
8989
90 The read() method accepts the C<allow_partial> parameter. If this is
91 non-zero then read() can return true on an incomplete image and set
90 The read() method accepts the C<allow_incomplete> parameter. If this
91 is non-zero then read() can return true on an incomplete image and set
9292 the C<i_incomplete> tag.
9393
9494 From Imager 0.68 you can supply most read() parameters to the new()
9999 my $img = Imager->new(file => $filename)
100100 or die "Cannot read $filename: ", Imager->errstr;
101101
102 =item write
102 =item write()
103103
104104 and the C<write()> method to write an image:
105105
106106 $img->write(file=>$filename, type=>$type)
107107 or die "Cannot write $filename: ", $img->errstr;
108108
109 =item read_multi
109 =item read_multi()
110110
111111 If you're reading from a format that supports multiple images per
112112 file, use the C<read_multi()> method:
117117 As with the read() method, Imager will normally detect the C<type>
118118 automatically.
119119
120 =item write_multi
120 =item write_multi()
121121
122122 and if you want to write multiple images to a single file use the
123123 C<write_multi()> method:
251251
252252 =item *
253253
254 C<callback> - Imager will make calls back to your supplied coderefs to
255 read, write and seek from/to/through the image file.
254 C<callback>, C<readcb>, C<writecb>, C<seekcb>, C<closecb> - Imager
255 will make calls back to your supplied coderefs to read, write and seek
256 from/to/through the image file. See L</"I/O Callbacks"> below for details.
257
258 =item *
259
260 C<io> - an L<Imager::IO> object.
261
262 =back
263
264 X<buffering>X<unbuffered>By default Imager will use buffered I/O when
265 reading or writing an image. You can disabled buffering for output by
266 supplying a C<< buffered => 0 >> parameter to C<write()> or
267 C<write_multi()>.
268
269 =head2 I/O Callbacks
256270
257271 When reading from a file you can use either C<callback> or C<readcb>
258272 to supply the read callback, and when writing C<callback> or
259273 C<writecb> to supply the write callback.
260274
261 When writing you can also supply the C<maxbuffer> option to set the
262 maximum amount of data that will be buffered before your write
263 callback is called. Note: the amount of data supplied to your
264 callback can be smaller or larger than this size.
265
266 The read callback is called with 2 parameters, the minimum amount of
267 data required, and the maximum amount that Imager will store in it's C
268 level buffer. You may want to return the minimum if you have a slow
269 data source, or the maximum if you have a fast source and want to
270 prevent many calls to your perl callback. The read data should be
271 returned as a scalar.
272
273 Your write callback takes exactly one parameter, a scalar containing
274 the data to be written. Return true for success.
275
276 The seek callback takes 2 parameters, a I<POSITION>, and a I<WHENCE>,
277 defined in the same way as perl's seek function.
278
279 You can also supply a C<closecb> which is called with no parameters
280 when there is no more data to be written. This could be used to flush
281 buffered data.
275 Some file formats, currently only C<TIFF>, also require a C<seekcb>
276 parameter to change position in the file. If no C<seekcb> parameter
277 is provided a default will be provided that fails.
278
279 You can also provide a C<closecb> parameter called when writing the
280 file is complete.
282281
283282 # contrived
284283 my $data;
289288 Imager->write_multi({ callback => \&mywrite, type => 'gif'}, @images)
290289 or die Imager->errstr;
291290
292 Note that for reading you'll almost always need to provide a
293 C<seekcb>.
294
295 =back
291 =head3 C<readcb>
292
293 The read callback is called with 2 parameters:
294
295 =over
296
297 =item *
298
299 C<size> - the minimum amount of data required.
300
301 =item *
302
303 C<maxsize> - previously this was the maximum amount of data returnable
304 - currently it's always the same as C<size>
305
306 =back
307
308 Your read callback should return the data as a scalar:
309
310 =over
311
312 =item *
313
314 on success, a string containing the bytes read.
315
316 =item *
317
318 on end of file, an empty string
319
320 =item *
321
322 on error, C<undef>.
323
324 =back
325
326 If your return value contains more data than C<size> Imager will
327 panic.
328
329 Your return value must not contain any characters over C<\xFF> or
330 Imager will panic.
331
332 =head3 C<writecb>
333
334 Your write callback takes exactly one parameter, a scalar containing
335 the data to be written.
336
337 Return true for success.
338
339 =head3 C<seekcb>
340
341 The seek callback takes 2 parameters, a I<POSITION>, and a I<WHENCE>,
342 defined in the same way as perl's seek function.
343
344 Previously you always needed a C<seekcb> callback if you called
345 Imager's L</read()> or L</read_multi()> without a C<type> parameter,
346 but this is no longer necessary unless the file handler requires
347 seeking, such as for TIFF files.
348
349 Returns the new position in the file, or -1 on failure.
350
351 =head3 C<closecb>
352
353 You can also supply a C<closecb> which is called with no parameters
354 when there is no more data to be written. This could be used to flush
355 buffered data.
356
357 Return true on success.
296358
297359 =head2 Guessing types
360 X<FORMATGUESS>
298361
299362 When writing to a file, if you don't supply a C<type> parameter Imager
300363 will attempt to guess it from the file name. This is done by calling
307370 =over
308371
309372 =item def_guess_type()
373 X<methods, def_guess_type()>
310374
311375 This is the default function Imager uses to derive a file type from a
312376 file name. This is a function, not a method.
2929
3030 =over
3131
32 =item filter
32 =item filter()
3333
3434 Parameters:
3535
88
99 sub new {
1010 my $class = shift;
11 my %hsh=(color=>Imager::Color->new(255,0,0,0),
11 my %hsh=(color=>Imager::Color->new(255,0,0,255),
1212 size=>15,
1313 @_);
1414
5050 my $class = shift;
5151 my $self = {};
5252 my ($file, $type, $id);
53 my %hsh=(color => Imager::Color->new(255,0,0,0),
53 my %hsh=(color => Imager::Color->new(255,0,0,255),
5454 size => 15,
5555 @_);
5656
1919 If you're writing an Imager file handler your code will be passed an
2020 Imager::IO object to write to or read from.
2121
22 =head1 METHODS
23
24 =over
25
26 =item write
22 X<UTF-8>X<Unicode>Note that Imager::IO can only work with collections of bytes -
23 if you need to read UTF-8 data you will need to read the bytes and
24 decode them. If you want to write UTF-8 data you will need to encode
25 your characters to bytes and write the bytes.
26
27 =head1 CONSTRUCTORS
28
29 =over
30
31 =item new_fd($fd)
32
33 Create a new I/O layer based on a file descriptor.
34
35 my $io = Imager::IO->new(fileno($fh));
36
37 =item new_buffer($data)
38
39 Create a new I/O layer based on a memory buffer.
40
41 The supplied variable must not be changed on the the life of the I/O
42 object.
43
44 Buffer I/O layers are read only.
45
46 =item new_cb($writecb, $readcb, $seekcb, $closecb)
47
48 Create a new I/O layer based on callbacks. See
49 L<Imager::Files/"I/O Callbacks"> for details on the behavior of
50 the callbacks.
51
52 =item new_bufchain()
53
54 Create a new C<bufchain> based I/O layer. This accumulates the file
55 data as a chain of buffers starting from an empty stream.
56
57 Use the L</slurp()> method to retrieve the accumulated content into a
58 perl string.
59
60 =back
61
62 =head1 BUFFERED I/O METHODS
63
64 These methods use buffered I/O to improve performance unless you call
65 set_buffered() to disable buffering.
66
67 Prior to Imager 0.86 the write and read methods performed raw I/O.
68
69 =over
70
71 =item write($data)
2772
2873 Call to write to the file. Returns the number of bytes written. The
2974 data provided may contain only characters \x00 to \xFF - characters
3681 isn't the number of bytes supplied you'll want to treat it as an error
3782 anyway.
3883
39 =item read
84 =item read($buffer, $size)
4085
4186 my $buffer;
4287 my $count = $io->read($buffer, $max_bytes);
4691 success or an empty list on failure. Note that a read of zero bytes
4792 is B<not> a failure, this indicates end of file.
4893
49 =item read2
94 =item read2($size)
5095
5196 my $buffer = $io->read2($max_bytes);
5297
5398 An alternative interface to read, that might be simpler to use in some
5499 cases.
55100
56 Returns the data read or an empty list.
57
58 =item seek
101 Returns the data read or an empty list. At end of file the data read
102 will be an empty string.
103
104 =item seek($offset, $whence)
59105
60106 my $new_position = $io->seek($offset, $whence);
61107
82128 Note that seeking past the end of the file may or may not result in an
83129 error.
84130
131 Any buffered output will be flushed, if flushing fails, seek() will
132 return -1.
133
85134 Returns the new position in the file, or -1 on error.
86135
87 =item close
136 =item getc()
137
138 Return the next byte from the stream.
139
140 Returns the ordinal of the byte or -1 on error or end of file.
141
142 while ((my $c = $io->getc) != -1) {
143 print chr($c);
144 }
145
146 =item gets()
147
148 =item gets($max_size)
149
150 =item gets($max_size, $end_of_line)
151
152 Returns the next line of input from the stream, as terminated by
153 C<end_of_line>.
154
155 The default C<max_size> is 8192.
156
157 The default C<end_of_line> is C<ord "\n">.
158
159 Returns nothing if the stream is in error or at end of file.
160
161 Returns the line as a string, including the line terminator (if one
162 was found) on success.
163
164 while (defined(my $line = $io->gets)) {
165 # do something with $line
166 }
167
168 =item peekc()
169
170 Return the buffered next character from the stream, loading the buffer
171 if necessary.
172
173 For an unbuffered stream a buffer will be setup and loaded with a
174 single character.
175
176 Returns the ordinal of the byte or -1 on error or end of file.
177
178 my $c = $io->peekc;
179
180 =item peekn($size)
181
182 Returns up to the next C<size> bytes from the file as a string.
183
184 Only up to the stream buffer size bytes (currently 8192) can be peeked.
185
186 This method ignores the buffering state of the stream.
187
188 Returns nothing on EOF.
189
190 my $s = $io->peekn(4);
191 if ($s =~ /^(II|MM)\*\0/) {
192 print "TIFF image";
193 }
194
195 =item putc($code)
196
197 Write a single character to the stream.
198
199 Returns C<code> on success, or -1 on failure.
200
201 =item close()
88202
89203 my $result = $io->close;
90204
91 Call when you're with the file. If the IO object is connected to a
92 file this won't close the file handle, but buffers may be flushed (if
93 any).
205 Call when you're done with the file. If the IO object is connected to
206 a file this won't close the file handle, but buffers may be flushed
207 (if any).
94208
95209 Returns 0 on success, -1 on failure.
96210
211 =item eof()
212
213 $io->eof
214
215 Test if the stream is at end of file. No further read requests will
216 be passed to your read callback until you seek().
217
218 =item error()
219
220 Test if the stream has encountered a read or write error.
221
222 my $data = $io->read2(100);
223 $io->error
224 and die "Failed";
225
226 When the stream has the error flag set no further read or write
227 requests will be passed to your callbacks until you seek.
228
229 =item flush()
230
231 $io->flush
232 or die "Flush error";
233
234 Flush any buffered output. This will not call lower write layers when
235 the stream has it's error flag set.
236
237 Returns a true value on success.
238
239 =item is_buffered()
240
241 Test if buffering is enabled for this stream.
242
243 Returns a true value if the stream is buffered.
244
245 =item set_buffered($enabled)
246
247 If C<$enabled> is a non-zero integer, enable buffering, other disable
248 it.
249
250 Disabling buffering will flush any buffered output, but any buffered
251 input will be retained and consumed by input methods.
252
253 Returns true if any buffered output was flushed successfully, false if
254 there was an error flushing output.
255
256 =back
257
258 =head1 RAW I/O METHODS
259
260 These call the underlying I/O abstraction directly.
261
262 =over
263
264 =item raw_write()
265
266 Call to write to the file. Returns the number of bytes written. The
267 data provided may contain only characters \x00 to \xFF - characters
268 outside this range will cause this method to croak().
269
270 If you supply a UTF-8 flagged string it will be converted to a byte
271 string, which may have a performance impact.
272
273 Returns -1 on error, though in most cases if the result of the write
274 isn't the number of bytes supplied you'll want to treat it as an error
275 anyway.
276
277 =item raw_read()
278
279 my $buffer;
280 my $count = $io->raw_read($buffer, $max_bytes);
281
282 Reads up to I<$max_bytes> bytes from the current position in the file
283 and stores them in I<$buffer>. Returns the number of bytes read on
284 success or an empty list on failure. Note that a read of zero bytes
285 is B<not> a failure, this indicates end of file.
286
287 =item raw_read2()
288
289 my $buffer = $io->raw_read2($max_bytes);
290
291 An alternative interface to raw_read, that might be simpler to use in some
292 cases.
293
294 Returns the data read or an empty list.
295
296 =item raw_seek()
297
298 my $new_position = $io->raw_seek($offset, $whence);
299
300 Seek to a new position in the file. Possible values for I<$whence> are:
301
302 =over
303
304 =item *
305
306 C<SEEK_SET> - I<$offset> is the new position in the file.
307
308 =item *
309
310 C<SEEK_CUR> - I<$offset> is the offset from the current position in
311 the file.
312
313 =item *
314
315 C<SEEK_END> - I<$offset> is the offset relative to the end of the
316 file.
317
318 =back
319
320 Note that seeking past the end of the file may or may not result in an
321 error.
322
323 Returns the new position in the file, or -1 on error.
324
325 =item raw_close()
326
327 my $result = $io->raw_close;
328
329 Call when you're done with the file. If the IO object is connected to
330 a file this won't close the file handle.
331
332 Returns 0 on success, -1 on failure.
333
334 =back
335
336 =head1 UTILITY METHODS
337
338 =over
339
340 =item slurp()
341
342 Retrieve the data accumulated from an I/O layer object created with
343 the new_bufchain() method.
344
345 my $data = $io->slurp;
346
347 =item dump()
348
349 Dump the internal buffering state of the I/O object to C<stderr>.
350
351 $io->dump();
352
97353 =back
98354
99355 =head1 AUTHOR
33 use Scalar::Util qw(reftype looks_like_number);
44 use Carp qw(croak);
55
6 $VERSION = "1.009";
6 $VERSION = "1.0010";
77
88 =head1 NAME
99
6060 use overload
6161 '*' => \&_mult,
6262 '+' => \&_add,
63 '""'=>\&_string;
63 '""'=>\&_string,
64 "eq" => \&_eq;
6465
6566 =item identity()
6667
373374 $out;
374375 }
375376
377 =item _eq
378
379 Implement the overloaded equality operator.
380
381 Provided for older perls that don't handle magic auto generation of eq
382 from "".
383
384 =cut
385
386 sub _eq {
387 my ($left, $right) = @_;
388
389 return $left . "" eq $right . "";
390 }
391
376392 =back
377393
378394 The following functions are shortcuts to the various constructors.
11 use strict;
22 use File::Spec;
33 use Config;
4 use Cwd ();
45
56 my @alt_transfer = qw/altname incsuffix libbase/;
67
129130 return;
130131 }
131132
133 sub _is_msvc {
134 return $Config{cc} eq "cl";
135 }
136
137 sub _lib_basename {
138 my ($base) = @_;
139
140 if (_is_msvc()) {
141 return $base;
142 }
143 else {
144 return "lib$base";
145 }
146 }
147
148 sub _lib_option {
149 my ($base) = @_;
150
151 if (_is_msvc()) {
152 return $base . $Config{_a};
153 }
154 else {
155 return "-l$base";
156 }
157 }
158
159 sub _quotearg {
160 my ($opt) = @_;
161
162 return $opt =~ /\s/ ? qq("$opt") : $opt;
163 }
164
132165 sub _probe_check {
133166 my ($req) = @_;
134167
138171 # synthesize a libcheck
139172 my $lext=$Config{'so'}; # Get extensions of libraries
140173 my $aext=$Config{'_a'};
174 my $basename = _lib_basename($libbase);
141175 $libcheck = sub {
142 -e File::Spec->catfile($_[0], "lib$libbase$aext")
143 || -e File::Spec->catfile($_[0], "lib$libbase.$lext")
176 -e File::Spec->catfile($_[0], "$basename$aext")
177 || -e File::Spec->catfile($_[0], "$basename.$lext")
144178 };
145179 }
146180
186220 push @libs, $req->{libopts};
187221 }
188222 elsif ($libbase) {
189 push @libs, "-l$libbase";
223 push @libs, _lib_option($libbase);
190224 }
191225 else {
192226 die "$req->{altname}: inccheck but no libbase or libopts";
194228
195229 return
196230 {
197 INC => "-I$found_incpath",
198 LIBS => "@libs",
231 INC => _quotearg("-I$found_incpath"),
232 LIBS => join(" ", map _quotearg($_), @libs),
199233 DEFINE => "",
200234 };
201235 }
289323 $^O eq "cygwin" ? "/usr/lib/w32api" : "",
290324 "/usr/lib",
291325 "/usr/local/lib",
326 _gcc_lib_paths(),
292327 );
328 }
329
330 sub _gcc_lib_paths {
331 $Config{gccversion}
332 or return;
333
334 my ($base_version) = $Config{gccversion} =~ /^([0-9]+)/
335 or return;
336
337 $base_version >= 4
338 or return;
339
340 my ($lib_line) = grep /^libraries:/, `$Config{cc} -print-search-dirs`
341 or return;
342 $lib_line =~ s/^libraries: =//;
343 chomp $lib_line;
344
345 return grep !/gcc/ && -d, split /:/, $lib_line;
293346 }
294347
295348 sub _inc_paths {
331384
332385 push @out, grep -d $_, split /\Q$Config{path_sep}/, $path;
333386 }
387
388 @out = map Cwd::realpath($_), @out;
389
390 my %seen;
391 @out = grep !$seen{$_}++, @out;
334392
335393 return @out;
336394 }
22 use Test::Builder;
33 require Exporter;
44 use vars qw(@ISA @EXPORT_OK $VERSION);
5 use Carp qw(croak);
56
67 $VERSION = "1.000";
78
1314 test_image_16
1415 test_image
1516 test_image_double
17 test_image_mono
18 test_image_gray
19 test_image_gray_16
20 test_image_named
1621 is_color1
1722 is_color3
1823 is_color4
320325 my $blue = Imager::Color->new(0, 0, 255, 255);
321326 my $red = Imager::Color->new(255, 0, 0, 255);
322327 my $img = Imager->new(xsize => 150, ysize => 150, bits => 16);
323 $img->box(filled => 1, color => $green, box => [ 70, 25, 130, 125 ]);
324 $img->box(filled => 1, color => $blue, box => [ 20, 25, 80, 125 ]);
328 $img->box(filled => 1, color => $green, box => [ 70, 24, 130, 124 ]);
329 $img->box(filled => 1, color => $blue, box => [ 20, 26, 80, 126 ]);
325330 $img->arc(x => 75, y => 75, r => 30, color => $red);
326331 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
327332
333338 my $blue = Imager::Color->new(0, 0, 255, 255);
334339 my $red = Imager::Color->new(255, 0, 0, 255);
335340 my $img = Imager->new(xsize => 150, ysize => 150, bits => 'double');
336 $img->box(filled => 1, color => $green, box => [ 70, 25, 130, 125 ]);
337 $img->box(filled => 1, color => $blue, box => [ 20, 25, 80, 125 ]);
341 $img->box(filled => 1, color => $green, box => [ 70, 24, 130, 124 ]);
342 $img->box(filled => 1, color => $blue, box => [ 20, 26, 80, 126 ]);
338343 $img->arc(x => 75, y => 75, r => 30, color => $red);
339344 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
340345
341346 $img;
347 }
348
349 sub test_image_gray {
350 my $g50 = Imager::Color->new(128, 128, 128);
351 my $g30 = Imager::Color->new(76, 76, 76);
352 my $g70 = Imager::Color->new(178, 178, 178);
353 my $img = Imager->new(xsize => 150, ysize => 150, channels => 1);
354 $img->box(filled => 1, color => $g50, box => [ 70, 24, 130, 124 ]);
355 $img->box(filled => 1, color => $g30, box => [ 20, 26, 80, 126 ]);
356 $img->arc(x => 75, y => 75, r => 30, color => $g70);
357 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
358
359 return $img;
360 }
361
362 sub test_image_gray_16 {
363 my $g50 = Imager::Color->new(128, 128, 128);
364 my $g30 = Imager::Color->new(76, 76, 76);
365 my $g70 = Imager::Color->new(178, 178, 178);
366 my $img = Imager->new(xsize => 150, ysize => 150, channels => 1, bits => 16);
367 $img->box(filled => 1, color => $g50, box => [ 70, 24, 130, 124 ]);
368 $img->box(filled => 1, color => $g30, box => [ 20, 26, 80, 126 ]);
369 $img->arc(x => 75, y => 75, r => 30, color => $g70);
370 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
371
372 return $img;
373 }
374
375 sub test_image_mono {
376 require Imager::Fill;
377 my $fh = Imager::Fill->new(hatch => 'check1x1');
378 my $img = Imager->new(xsize => 150, ysize => 150, type => "paletted");
379 my $black = Imager::Color->new(0, 0, 0);
380 my $white = Imager::Color->new(255, 255, 255);
381 $img->addcolors(colors => [ $black, $white ]);
382 $img->box(fill => $fh, box => [ 70, 24, 130, 124 ]);
383 $img->box(filled => 1, color => $white, box => [ 20, 26, 80, 126 ]);
384 $img->arc(x => 75, y => 75, r => 30, color => $black, aa => 0);
385
386 return $img;
387 }
388
389 my %name_to_sub =
390 (
391 basic => \&test_image,
392 basic16 => \&test_image_16,
393 basic_double => \&test_image_double,
394 gray => \&test_image_gray,
395 gray16 => \&test_image_gray_16,
396 mono => \&test_image_mono,
397 );
398
399 sub test_image_named {
400 my $name = shift
401 or croak("No name supplied to test_image_named()");
402 my $sub = $name_to_sub{$name}
403 or croak("Unknown name $name supplied to test_image_named()");
404
405 return $sub->();
342406 }
343407
344408 sub _low_image_diff_check {
821885
822886 =item test_image()
823887
824 Returns a 150x150x3 8-bit/sample OO test image.
888 Returns a 150x150x3 8-bit/sample OO test image. Name: C<basic>.
825889
826890 =item test_image_16()
827891
828 Returns a 150x150x3 16-bit/sample OO test image.
892 Returns a 150x150x3 16-bit/sample OO test image. Name: C<basic16>
829893
830894 =item test_image_double()
831895
832 Returns a 150x150x3 double/sample OO test image.
896 Returns a 150x150x3 double/sample OO test image. Name: C<basic_double>.
897
898 =item test_image_gray()
899
900 Returns a 150x150 single channel OO test image. Name: C<gray>.
901
902 =item test_image_gray_16()
903
904 Returns a 150x150 16-bit/sample single channel OO test image. Name:
905 C<gray16>.
906
907 =item test_image_mono()
908
909 Returns a 150x150 bilevel image that passes the is_bilevel() test.
910 Name: C<mono>.
911
912 =item test_image_named($name)
913
914 Return one of the other test images above based on name.
833915
834916 =item color_cmp($c1, $c2)
835917
+113
-225
pnm.c less more
3535 */
3636
3737
38 #define BSIZ 1024
3938 #define misspace(x) (x==' ' || x=='\n' || x=='\r' || x=='\t' || x=='\f' || x=='\v')
4039 #define misnumber(x) (x <= '9' && x>='0')
4140
4241 static char *typenames[]={"ascii pbm", "ascii pgm", "ascii ppm", "binary pbm", "binary pgm", "binary ppm"};
4342
4443 /*
45 * Type to encapsulate the local buffer
46 * management skipping over in a file
47 */
48
49 typedef struct {
50 io_glue *ig;
51 int len;
52 int cp;
53 char buf[BSIZ];
54 } mbuf;
55
56
57 static
58 void init_buf(mbuf *mb, io_glue *ig) {
59 mb->len = 0;
60 mb->cp = 0;
61 mb->ig = ig;
62 }
63
64
65
66 /*
67 =item gnext(mbuf *mb)
68
69 Fetches a character and advances in stream by one character.
70 Returns a pointer to the byte or NULL on failure (internal).
71
72 mb - buffer object
44 =item skip_spaces(ig)
45
46 Advances in stream until it is positioned at a
47 non white space character. (internal)
48
49 ig - io_glue
7350
7451 =cut
7552 */
7653
77 #define gnext(mb) (((mb)->cp == (mb)->len) ? gnextf(mb) : (mb)->buf + (mb)->cp++)
78
79 static
80 char *
81 gnextf(mbuf *mb) {
82 io_glue *ig = mb->ig;
83 if (mb->cp == mb->len) {
84 mb->cp = 0;
85 mb->len = ig->readcb(ig, mb->buf, BSIZ);
86 if (mb->len == -1) {
87 i_push_error(errno, "file read error");
88 mm_log((1, "i_readpnm: read error\n"));
89 return NULL;
90 }
91 if (mb->len == 0) {
92 mm_log((1, "i_readpnm: end of file\n"));
93 return NULL;
94 }
95 }
96 return &mb->buf[mb->cp++];
54 static
55 int
56 skip_spaces(io_glue *ig) {
57 int c;
58 while( (c = i_io_peekc(ig)) != EOF && misspace(c) ) {
59 if ( i_io_getc(ig) == EOF )
60 break;
61 }
62 if (c == EOF)
63 return 0;
64
65 return 1;
9766 }
9867
9968
10069 /*
101 =item gpeek(mbuf *mb)
102
103 Fetches a character but does NOT advance. Returns a pointer to
104 the byte or NULL on failure (internal).
105
106 mb - buffer object
70 =item skip_comment(ig)
71
72 Advances in stream over whitespace and a comment if one is found. (internal)
73
74 ig - io_glue object
10775
10876 =cut
10977 */
11078
111 #define gpeek(mb) ((mb)->cp == (mb)->len ? gpeekf(mb) : (mb)->buf + (mb)->cp)
112
113 static
114 char *
115 gpeekf(mbuf *mb) {
116 io_glue *ig = mb->ig;
117 if (mb->cp == mb->len) {
118 mb->cp = 0;
119 mb->len = ig->readcb(ig, mb->buf, BSIZ);
120 if (mb->len == -1) {
121 i_push_error(errno, "read error");
122 mm_log((1, "i_readpnm: read error\n"));
123 return NULL;
124 }
125 if (mb->len == 0) {
126 mm_log((1, "i_readpnm: end of file\n"));
127 return NULL;
128 }
129 }
130 return &mb->buf[mb->cp];
131 }
132
79 static
13380 int
134 gread(mbuf *mb, unsigned char *buf, size_t read_size) {
135 int total_read = 0;
136 if (mb->cp != mb->len) {
137 int avail_size = mb->len - mb->cp;
138 int use_size = read_size > avail_size ? avail_size : read_size;
139 memcpy(buf, mb->buf+mb->cp, use_size);
140 mb->cp += use_size;
141 total_read += use_size;
142 read_size -= use_size;
143 buf += use_size;
144 }
145 if (read_size) {
146 io_glue *ig = mb->ig;
147 int read_res = i_io_read(ig, buf, read_size);
148 if (read_res >= 0) {
149 total_read += read_res;
150 }
151 }
152 return total_read;
81 skip_comment(io_glue *ig) {
82 int c;
83
84 if (!skip_spaces(ig))
85 return 0;
86
87 if ((c = i_io_peekc(ig)) == EOF)
88 return 0;
89
90 if (c == '#') {
91 while( (c = i_io_peekc(ig)) != EOF && (c != '\n' && c != '\r') ) {
92 if ( i_io_getc(ig) == EOF )
93 break;
94 }
95 }
96 if (c == EOF)
97 return 0;
98
99 return 1;
153100 }
154101
155102
156103 /*
157 =item skip_spaces(mb)
158
159 Advances in stream until it is positioned at a
160 non white space character. (internal)
104 =item gnum(mb, i)
105
106 Fetches the next number from stream and stores in i, returns true
107 on success else false.
161108
162109 mb - buffer object
110 i - integer to store result in
163111
164112 =cut
165113 */
166114
167115 static
168116 int
169 skip_spaces(mbuf *mb) {
170 char *cp;
171 while( (cp = gpeek(mb)) && misspace(*cp) ) if ( !gnext(mb) ) break;
172 if (!cp) return 0;
173 return 1;
174 }
175
176
177 /*
178 =item skip_comment(mb)
179
180 Advances in stream over whitespace and a comment if one is found. (internal)
181
182 mb - buffer object
183
184 =cut
185 */
186
187 static
188 int
189 skip_comment(mbuf *mb) {
190 char *cp;
191
192 if (!skip_spaces(mb)) return 0;
193
194 if (!(cp = gpeek(mb))) return 0;
195 if (*cp == '#') {
196 while( (cp = gpeek(mb)) && (*cp != '\n' && *cp != '\r') ) {
197 if ( !gnext(mb) ) break;
198 }
199 }
200 if (!cp) return 0;
201
202 return 1;
203 }
204
205
206 /*
207 =item gnum(mb, i)
208
209 Fetches the next number from stream and stores in i, returns true
210 on success else false.
211
212 mb - buffer object
213 i - integer to store result in
214
215 =cut
216 */
217
218 static
219 int
220 gnum(mbuf *mb, int *i) {
221 char *cp;
117 gnum(io_glue *ig, int *i) {
118 int c;
222119 *i = 0;
223120
224 if (!skip_spaces(mb)) return 0;
225
226 if (!(cp = gpeek(mb)))
121 if (!skip_spaces(ig)) return 0;
122
123 if ((c = i_io_peekc(ig)) == EOF)
227124 return 0;
228 if (!misnumber(*cp))
125 if (!misnumber(c))
229126 return 0;
230 while( (cp = gpeek(mb)) && misnumber(*cp) ) {
231 int work = *i*10+(*cp-'0');
127 while( (c = i_io_peekc(ig)) != EOF && misnumber(c) ) {
128 int work = *i * 10 + (c - '0');
232129 if (work < *i) {
233130 /* overflow */
234131 i_push_error(0, "integer overflow");
235132 return 0;
236133 }
237134 *i = work;
238 cp = gnext(mb);
239 }
135 i_io_getc(ig);
136 }
137
240138 return 1;
241139 }
242140
243141 static
244142 i_img *
245 read_pgm_ppm_bin8(mbuf *mb, i_img *im, int width, int height,
143 read_pgm_ppm_bin8(io_glue *ig, i_img *im, int width, int height,
246144 int channels, int maxval, int allow_incomplete) {
247145 i_color *line, *linep;
248146 int read_size;
256154 for(y=0;y<height;y++) {
257155 linep = line;
258156 readp = read_buf;
259 if (gread(mb, read_buf, read_size) != read_size) {
157 if (i_io_read(ig, read_buf, read_size) != read_size) {
260158 myfree(line);
261159 myfree(read_buf);
262160 if (allow_incomplete) {
300198
301199 static
302200 i_img *
303 read_pgm_ppm_bin16(mbuf *mb, i_img *im, int width, int height,
201 read_pgm_ppm_bin16(io_glue *ig, i_img *im, int width, int height,
304202 int channels, int maxval, int allow_incomplete) {
305203 i_fcolor *line, *linep;
306204 int read_size;
314212 for(y=0;y<height;y++) {
315213 linep = line;
316214 readp = read_buf;
317 if (gread(mb, read_buf, read_size) != read_size) {
215 if (i_io_read(ig, read_buf, read_size) != read_size) {
318216 myfree(line);
319217 myfree(read_buf);
320218 if (allow_incomplete) {
348246
349247 static
350248 i_img *
351 read_pbm_bin(mbuf *mb, i_img *im, int width, int height, int allow_incomplete) {
249 read_pbm_bin(io_glue *ig, i_img *im, int width, int height, int allow_incomplete) {
352250 i_palidx *line, *linep;
353251 int read_size;
354252 unsigned char *read_buf, *readp;
359257 read_size = (width + 7) / 8;
360258 read_buf = mymalloc(read_size);
361259 for(y = 0; y < height; y++) {
362 if (gread(mb, read_buf, read_size) != read_size) {
260 if (i_io_read(ig, read_buf, read_size) != read_size) {
363261 myfree(line);
364262 myfree(read_buf);
365263 if (allow_incomplete) {
398296 */
399297 static
400298 i_img *
401 read_pbm_ascii(mbuf *mb, i_img *im, int width, int height, int allow_incomplete) {
299 read_pbm_ascii(io_glue *ig, i_img *im, int width, int height, int allow_incomplete) {
402300 i_palidx *line, *linep;
403301 int x, y;
404302
406304 for(y = 0; y < height; y++) {
407305 linep = line;
408306 for(x = 0; x < width; ++x) {
409 char *cp;
410 skip_spaces(mb);
411 if (!(cp = gnext(mb)) || (*cp != '0' && *cp != '1')) {
307 int c;
308 skip_spaces(ig);
309 if ((c = i_io_getc(ig)) == EOF || (c != '0' && c != '1')) {
412310 myfree(line);
413311 if (allow_incomplete) {
414312 i_tags_setn(&im->tags, "i_incomplete", 1);
416314 return im;
417315 }
418316 else {
419 if (cp)
317 if (c != EOF)
420318 i_push_error(0, "invalid data for ascii pnm");
421319 else
422320 i_push_error(0, "short read - file truncated?");
424322 return NULL;
425323 }
426324 }
427 *linep++ = *cp == '0' ? 0 : 1;
325 *linep++ = c == '0' ? 0 : 1;
428326 }
429327 i_ppal(im, 0, width, y, line);
430328 }
435333
436334 static
437335 i_img *
438 read_pgm_ppm_ascii(mbuf *mb, i_img *im, int width, int height, int channels,
336 read_pgm_ppm_ascii(io_glue *ig, i_img *im, int width, int height, int channels,
439337 int maxval, int allow_incomplete) {
440338 i_color *line, *linep;
441339 int x, y, ch;
448346 for(ch=0; ch<channels; ch++) {
449347 int sample;
450348
451 if (!gnum(mb, &sample)) {
349 if (!gnum(ig, &sample)) {
452350 myfree(line);
453351 if (allow_incomplete) {
454352 i_tags_setn(&im->tags, "i_incomplete", 1);
456354 return im;
457355 }
458356 else {
459 if (gpeek(mb))
357 if (i_io_peekc(ig) != EOF)
460358 i_push_error(0, "invalid data for ascii pnm");
461359 else
462360 i_push_error(0, "short read - file truncated?");
479377
480378 static
481379 i_img *
482 read_pgm_ppm_ascii_16(mbuf *mb, i_img *im, int width, int height,
380 read_pgm_ppm_ascii_16(io_glue *ig, i_img *im, int width, int height,
483381 int channels, int maxval, int allow_incomplete) {
484382 i_fcolor *line, *linep;
485383 int x, y, ch;
492390 for(ch=0; ch<channels; ch++) {
493391 int sample;
494392
495 if (!gnum(mb, &sample)) {
393 if (!gnum(ig, &sample)) {
496394 myfree(line);
497395 if (allow_incomplete) {
498396 i_tags_setn(&im->tags, "i_incomplete", 1);
500398 return im;
501399 }
502400 else {
503 if (gpeek(mb))
401 if (i_io_peekc(ig) != EOF)
504402 i_push_error(0, "invalid data for ascii pnm");
505403 else
506404 i_push_error(0, "short read - file truncated?");
531429
532430 =cut
533431 */
534 static i_img *i_readpnm_wiol_low( mbuf*, int);
535432
536433 i_img *
537 i_readpnm_wiol(io_glue *ig, int allow_incomplete) {
538 mbuf buf;
539 io_glue_commit_types(ig);
540 init_buf(&buf, ig);
541
542 return i_readpnm_wiol_low( &buf, allow_incomplete );
543 }
544
545 static i_img *
546 i_readpnm_wiol_low( mbuf *buf, int allow_incomplete) {
434 i_readpnm_wiol( io_glue *ig, int allow_incomplete) {
547435 i_img* im;
548436 int type;
549437 int width, height, maxval, channels;
550438 int rounder;
551 char *cp;
439 int c;
552440
553441 i_clear_error();
554 mm_log((1,"i_readpnm(ig %p, allow_incomplete %d)\n", buf->ig, allow_incomplete));
555
556 cp = gnext(buf);
557
558 if (!cp || *cp != 'P') {
442 mm_log((1,"i_readpnm(ig %p, allow_incomplete %d)\n", ig, allow_incomplete));
443
444 c = i_io_getc(ig);
445
446 if (c != 'P') {
559447 i_push_error(0, "bad header magic, not a PNM file");
560448 mm_log((1, "i_readpnm: Could not read header of file\n"));
561449 return NULL;
562450 }
563451
564 if ( !(cp = gnext(buf)) ) {
452 if ((c = i_io_getc(ig)) == EOF ) {
565453 mm_log((1, "i_readpnm: Could not read header of file\n"));
566454 return NULL;
567455 }
568456
569 type = *cp-'0';
457 type = c - '0';
570458
571459 if (type < 1 || type > 6) {
572460 i_push_error(0, "unknown PNM file type, not a PNM file");
574462 return NULL;
575463 }
576464
577 if ( !(cp = gnext(buf)) ) {
465 if ( (c = i_io_getc(ig)) == EOF ) {
578466 mm_log((1, "i_readpnm: Could not read header of file\n"));
579467 return NULL;
580468 }
581469
582 if ( !misspace(*cp) ) {
470 if ( !misspace(c) ) {
583471 i_push_error(0, "unexpected character, not a PNM file");
584472 mm_log((1, "i_readpnm: Not a pnm file\n"));
585473 return NULL;
590478
591479 /* Read sizes and such */
592480
593 if (!skip_comment(buf)) {
481 if (!skip_comment(ig)) {
594482 i_push_error(0, "while skipping to width");
595483 mm_log((1, "i_readpnm: error reading before width\n"));
596484 return NULL;
597485 }
598486
599 if (!gnum(buf, &width)) {
487 if (!gnum(ig, &width)) {
600488 i_push_error(0, "could not read image width");
601489 mm_log((1, "i_readpnm: error reading width\n"));
602490 return NULL;
603491 }
604492
605 if (!skip_comment(buf)) {
493 if (!skip_comment(ig)) {
606494 i_push_error(0, "while skipping to height");
607495 mm_log((1, "i_readpnm: error reading before height\n"));
608496 return NULL;
609497 }
610498
611 if (!gnum(buf, &height)) {
499 if (!gnum(ig, &height)) {
612500 i_push_error(0, "could not read image height");
613501 mm_log((1, "i_readpnm: error reading height\n"));
614502 return NULL;
615503 }
616504
617505 if (!(type == 1 || type == 4)) {
618 if (!skip_comment(buf)) {
506 if (!skip_comment(ig)) {
619507 i_push_error(0, "while skipping to maxval");
620508 mm_log((1, "i_readpnm: error reading before maxval\n"));
621509 return NULL;
622510 }
623511
624 if (!gnum(buf, &maxval)) {
512 if (!gnum(ig, &maxval)) {
625513 i_push_error(0, "could not read maxval");
626514 mm_log((1, "i_readpnm: error reading maxval\n"));
627515 return NULL;
641529 } else maxval=1;
642530 rounder = maxval / 2;
643531
644 if (!(cp = gnext(buf)) || !misspace(*cp)) {
532 if ((c = i_io_getc(ig)) == EOF || !misspace(c)) {
645533 i_push_error(0, "garbage in header, invalid PNM file");
646534 mm_log((1, "i_readpnm: garbage in header\n"));
647535 return NULL;
673561
674562 switch (type) {
675563 case 1: /* Ascii types */
676 im = read_pbm_ascii(buf, im, width, height, allow_incomplete);
564 im = read_pbm_ascii(ig, im, width, height, allow_incomplete);
677565 break;
678566
679567 case 2:
680568 case 3:
681569 if (maxval > 255)
682 im = read_pgm_ppm_ascii_16(buf, im, width, height, channels, maxval, allow_incomplete);
570 im = read_pgm_ppm_ascii_16(ig, im, width, height, channels, maxval, allow_incomplete);
683571 else
684 im = read_pgm_ppm_ascii(buf, im, width, height, channels, maxval, allow_incomplete);
572 im = read_pgm_ppm_ascii(ig, im, width, height, channels, maxval, allow_incomplete);
685573 break;
686574
687575 case 4: /* binary pbm */
688 im = read_pbm_bin(buf, im, width, height, allow_incomplete);
576 im = read_pbm_bin(ig, im, width, height, allow_incomplete);
689577 break;
690578
691579 case 5: /* binary pgm */
692580 case 6: /* binary ppm */
693581 if (maxval > 255)
694 im = read_pgm_ppm_bin16(buf, im, width, height, channels, maxval, allow_incomplete);
582 im = read_pgm_ppm_bin16(ig, im, width, height, channels, maxval, allow_incomplete);
695583 else
696 im = read_pgm_ppm_bin8(buf, im, width, height, channels, maxval, allow_incomplete);
584 im = read_pgm_ppm_bin8(ig, im, width, height, channels, maxval, allow_incomplete);
697585 break;
698586
699587 default:
724612 i_img **i_readpnm_multi_wiol(io_glue *ig, int *count, int allow_incomplete) {
725613 i_img **results = NULL;
726614 i_img *img = NULL;
727 char *cp = NULL;
728 mbuf buf;
615 char c = EOF;
729616 int result_alloc = 0,
730617 value = 0,
731618 eof = 0;
732619 *count=0;
733 io_glue_commit_types(ig);
734 init_buf(&buf, ig);
620
735621 do {
736622 mm_log((1, "read image %i\n", 1+*count));
737 img = i_readpnm_wiol_low( &buf, allow_incomplete );
623 img = i_readpnm_wiol( ig, allow_incomplete );
738624 if( !img ) {
739625 free_images( results, *count );
740626 return NULL;
757643 if( i_tags_get_int(&img->tags, "i_incomplete", 0, &value ) && value) {
758644 eof = 1;
759645 }
760 else if( skip_spaces( &buf ) && ( cp=gpeek( &buf ) ) && *cp == 'P' ) {
646 else if( skip_spaces( ig ) && ( c=i_io_peekc( ig ) ) != EOF && c == 'P' ) {
761647 eof = 0;
762648 }
763649 else {
892778 /* Add code to get the filename info from the iolayer */
893779 /* Also add code to check for mmapped code */
894780
895 io_glue_commit_types(ig);
896
897781 if (i_img_is_monochrome(im, &zero_is_white)) {
898 return write_pbm(im, ig, zero_is_white);
782 if (!write_pbm(im, ig, zero_is_white))
783 return 0;
899784 }
900785 else {
901786 int type;
927812 sprintf(header,"P%d\n#CREATOR: Imager\n%" i_DF " %" i_DF"\n%d\n",
928813 type, i_DFc(im->xsize), i_DFc(im->ysize), maxval);
929814
930 if (ig->writecb(ig,header,strlen(header)) != strlen(header)) {
815 if (i_io_write(ig,header,strlen(header)) != strlen(header)) {
931816 i_push_error(errno, "could not write ppm header");
932817 mm_log((1,"i_writeppm: unable to write ppm header.\n"));
933818 return(0);
935820
936821 if (!im->virtual && im->bits == i_8_bits && im->type == i_direct_type
937822 && im->channels == want_channels) {
938 if (ig->writecb(ig,im->idata,im->bytes) != im->bytes) {
823 if (i_io_write(ig,im->idata,im->bytes) != im->bytes) {
939824 i_push_error(errno, "could not write ppm data");
940825 return 0;
941826 }
949834 return 0;
950835 }
951836 }
952 ig->closecb(ig);
837 if (i_io_close(ig)) {
838 i_push_errorf(i_io_error(ig), "Error closing stream: %d", i_io_error(ig));
839 return 0;
840 }
953841
954842 return(1);
955843 }
6969
7070 i_clear_error();
7171
72 io_glue_commit_types(ig);
7372 mm_log((1, "i_readraw(ig %p,x %" i_DF ",y %" i_DF ",datachannels %d,storechannels %d,intrl %d)\n",
7473 ig, i_DFc(x), i_DFc(y), datachannels, storechannels, intrl));
7574
101100
102101 k=0;
103102 while( k<im->ysize ) {
104 rc = ig->readcb(ig, inbuffer, inbuflen);
103 rc = i_io_read(ig, inbuffer, inbuflen);
105104 if (rc != inbuflen) {
106105 if (rc < 0)
107106 i_push_error(0, "error reading file");
135134 i_writeraw_wiol(i_img* im, io_glue *ig) {
136135 ssize_t rc;
137136
138 io_glue_commit_types(ig);
139137 i_clear_error();
140138 mm_log((1,"writeraw(im %p,ig %p)\n", im, ig));
141139
142140 if (im == NULL) { mm_log((1,"Image is empty\n")); return(0); }
143141 if (!im->virtual) {
144 rc = ig->writecb(ig,im->idata,im->bytes);
142 rc = i_io_write(ig,im->idata,im->bytes);
145143 if (rc != im->bytes) {
146144 i_push_error(errno, "Could not write to file");
147145 mm_log((1,"i_writeraw: Couldn't write to file\n"));
158156 rc = line_size;
159157 while (rc == line_size && y < im->ysize) {
160158 i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
161 rc = ig->writecb(ig, data, line_size);
159 rc = i_io_write(ig, data, line_size);
162160 ++y;
163161 }
164162 if (rc != line_size) {
177175 rc = line_size;
178176 while (rc == line_size && y < im->ysize) {
179177 i_gpal(im, 0, im->xsize, y, data);
180 rc = ig->writecb(ig, data, line_size);
178 rc = i_io_write(ig, data, line_size);
181179 ++y;
182180 }
183181 myfree(data);
188186 }
189187 }
190188
191 ig->closecb(ig);
189 if (i_io_close(ig))
190 return 0;
192191
193192 return(1);
194193 }
332332 }
333333 else if (*src) {
334334 for (ch = 0; ch < im->channels; ++ch) {
335 IM_WORK_T work = (destc->channel[ch] * (IM_SAMPLE_MAX - *src)
336 + srcc->channel[ch] * *src) / IM_SAMPLE_MAX;
335 IM_WORK_T work = (destc->channel[ch] * (255 - *src)
336 + srcc->channel[ch] * *src) / 255.0;
337337 destc->channel[ch] = IM_LIMIT(work);
338338 }
339339 }
137137 expensive CGI request to generate the image, but it means you need
138138 some mechanism to manage the files (for example, a cron job to delete
139139 old files), and you need to make some directory under the document
140 root writeable by the user that your web server runs CGI programs as,
140 root writable by the user that your web server runs CGI programs as,
141141 which may be a security concern.
142142
143143 Also, if you're generating large numbers of large images, you may end
2525 return $pod->{identifiers} || [];
2626 }
2727
28 sub _get_syms {
29 my ($self, $package) = @_;
30
31 if ($self->{module}) {
32 eval "require $self->{module}";
33 return if $@;
34
35 # fake out require
36 (my $file = $package) =~ s(::)(/)g;
37 $file .= ".pm";
38 $INC{$file} = 1;
39 }
40
41 return $self->SUPER::_get_syms($package);
42 }
43
2844 1;
00 #!perl -w
11 use strict;
2 use Test::More tests => 68;
2 use Test::More tests => 246;
33 # for SEEK_SET etc, Fcntl doesn't provide these in 5.005_03
44 use IO::Seekable;
55
66 BEGIN { use_ok(Imager => ':all') };
77
88 -d "testout" or mkdir "testout";
9
10 $| = 1;
911
1012 Imager->open_log(log => "testout/t07iolayer.log");
1113
3032 binmode(FH);
3133 $data = <FH>;
3234 close(FH);
33 my $IO3 = Imager::io_new_buffer($data);
35 my $IO3 = Imager::IO->new_buffer($data);
3436 #undef($data);
3537 $im = Imager::i_readpnm_wiol($IO3, -1);
3638
4042 open(FH, "<testimg/penguin-base.ppm") or die $!;
4143 binmode(FH);
4244 $fd = fileno(FH);
43 my $IO4 = Imager::io_new_fd( $fd );
45 my $IO4 = Imager::IO->new_fd( $fd );
4446 my $im2 = Imager::i_readpnm_wiol($IO4, -1);
4547 close(FH);
4648 undef($IO4);
7678 $pos += length $out;
7779 $out;
7880 }
79 my $IO7 = Imager::io_new_cb(undef, \&io_reader, undef, undef);
81 my $IO7 = Imager::IO->new_cb(undef, \&io_reader, undef, undef);
8082 ok($IO7, "making readcb object");
8183 my $im4 = Imager::i_readpnm_wiol($IO7, -1);
8284 ok($im4, "read from cb");
125127 my $io9 = Imager::io_new_buffer($buf_data);
126128 is(ref $io9, "Imager::IO", "check class");
127129 my $work;
128 is($io9->read($work, 4), 4, "read 4 from buffer object");
130 is($io9->raw_read($work, 4), 4, "read 4 from buffer object");
129131 is($work, "Test", "check data read");
130 is($io9->read($work, 5), 5, "read the rest");
132 is($io9->raw_read($work, 5), 5, "read the rest");
131133 is($work, " data", "check data read");
132 is($io9->seek(5, SEEK_SET), 5, "seek");
133 is($io9->read($work, 5), 4, "short read");
134 is($io9->raw_seek(5, SEEK_SET), 5, "seek");
135 is($io9->raw_read($work, 5), 4, "short read");
134136 is($work, "data", "check data read");
135 is($io9->seek(-1, SEEK_CUR), 8, "seek relative");
136 is($io9->seek(-5, SEEK_END), 4, "seek relative to end");
137 is($io9->seek(-10, SEEK_CUR), -1, "seek failure");
137 is($io9->raw_seek(-1, SEEK_CUR), 8, "seek relative");
138 is($io9->raw_seek(-5, SEEK_END), 4, "seek relative to end");
139 is($io9->raw_seek(-10, SEEK_CUR), -1, "seek failure");
138140 undef $io9;
139141 }
140142 {
141 my $io = Imager::io_new_bufchain();
143 my $io = Imager::IO->new_bufchain();
142144 is(ref $io, "Imager::IO", "check class");
143 is($io->write("testdata"), 8, "check write");
144 is($io->seek(-8, SEEK_CUR), 0, "seek relative");
145 is($io->raw_write("testdata"), 8, "check write");
146 is($io->raw_seek(-8, SEEK_CUR), 0, "seek relative");
145147 my $work;
146 is($io->read($work, 8), 8, "check read");
148 is($io->raw_read($work, 8), 8, "check read");
147149 is($work, "testdata", "check data read");
148 is($io->seek(-3, SEEK_END), 5, "seek end relative");
149 is($io->read($work, 5), 3, "short read");
150 is($io->raw_seek(-3, SEEK_END), 5, "seek end relative");
151 is($io->raw_read($work, 5), 3, "short read");
150152 is($work, "ata", "check read data");
151 is($io->seek(4, SEEK_SET), 4, "absolute seek to write some");
152 is($io->write("testdata"), 8, "write");
153 is($io->seek(0, SEEK_CUR), 12, "check size");
154 $io->close();
153 is($io->raw_seek(4, SEEK_SET), 4, "absolute seek to write some");
154 is($io->raw_write("testdata"), 8, "write");
155 is($io->raw_seek(0, SEEK_CUR), 12, "check size");
156 $io->raw_close();
155157
156158 # grab the data
157159 my $data = Imager::io_slurp($io);
162164 my $fail_io = Imager::io_new_cb(\&fail_write, \&fail_read, \&fail_seek, undef, 1);
163165 # scalar context
164166 my $buffer;
165 my $read_result = $fail_io->read($buffer, 10);
167 my $read_result = $fail_io->raw_read($buffer, 10);
166168 is($read_result, undef, "read failure undef in scalar context");
167 my @read_result = $fail_io->read($buffer, 10);
169 my @read_result = $fail_io->raw_read($buffer, 10);
168170 is(@read_result, 0, "empty list in list context");
169 $read_result = $fail_io->read2(10);
170 is($read_result, undef, "read2 failure (scalar)");
171 @read_result = $fail_io->read2(10);
172 is(@read_result, 0, "read2 failure (list)");
173
174 my $write_result = $fail_io->write("test");
171 $read_result = $fail_io->raw_read2(10);
172 is($read_result, undef, "raw_read2 failure (scalar)");
173 @read_result = $fail_io->raw_read2(10);
174 is(@read_result, 0, "raw_read2 failure (list)");
175
176 my $write_result = $fail_io->raw_write("test");
175177 is($write_result, -1, "failed write");
176178
177 my $seek_result = $fail_io->seek(-1, SEEK_SET);
179 my $seek_result = $fail_io->raw_seek(-1, SEEK_SET);
178180 is($seek_result, -1, "failed seek");
179181 }
180182
182184 my $good_io = Imager::io_new_cb(\&good_write, \&good_read, \&good_seek, undef, 1);
183185 # scalar context
184186 my $buffer;
185 my $read_result = $good_io->read($buffer, 10);
186 is($read_result, 10, "read success (scalar)");
187 is($buffer, "testdatate", "check data");
188 my @read_result = $good_io->read($buffer, 10);
189 is_deeply(\@read_result, [ 10 ], "read success (list)");
190 is($buffer, "testdatate", "check data");
191 $read_result = $good_io->read2(10);
192 is($read_result, "testdatate", "read2 success (scalar)");
193 @read_result = $good_io->read2(10);
194 is_deeply(\@read_result, [ "testdatate" ], "read2 success (list)");
187 my $read_result = $good_io->raw_read($buffer, 10);
188 is($read_result, 8, "read success (scalar)");
189 is($buffer, "testdata", "check data");
190 my @read_result = $good_io->raw_read($buffer, 10);
191 is_deeply(\@read_result, [ 8 ], "read success (list)");
192 is($buffer, "testdata", "check data");
193 $read_result = $good_io->raw_read2(10);
194 is($read_result, "testdata", "read2 success (scalar)");
195 @read_result = $good_io->raw_read2(10);
196 is_deeply(\@read_result, [ "testdata" ], "read2 success (list)");
195197 }
196198
197199 { # end of file
198200 my $eof_io = Imager::io_new_cb(undef, \&eof_read, undef, undef, 1);
199201 my $buffer;
200 my $read_result = $eof_io->read($buffer, 10);
202 my $read_result = $eof_io->raw_read($buffer, 10);
201203 is($read_result, 0, "read eof (scalar)");
202204 is($buffer, '', "check data");
203 my @read_result = $eof_io->read($buffer, 10);
205 my @read_result = $eof_io->raw_read($buffer, 10);
204206 is_deeply(\@read_result, [ 0 ], "read eof (list)");
205207 is($buffer, '', "check data");
206208 }
207209
208210 { # no callbacks
209211 my $none_io = Imager::io_new_cb(undef, undef, undef, undef, 0);
210 is($none_io->write("test"), -1, "write with no writecb should fail");
212 is($none_io->raw_write("test"), -1, "write with no writecb should fail");
211213 my $buffer;
212 is($none_io->read($buffer, 10), undef, "read with no readcb should fail");
213 is($none_io->seek(0, SEEK_SET), -1, "seek with no seekcb should fail");
214 is($none_io->raw_read($buffer, 10), undef, "read with no readcb should fail");
215 is($none_io->raw_seek(0, SEEK_SET), -1, "seek with no seekcb should fail");
214216 }
215217
216218 SKIP:
223225 is(ord $data, 0x100, "make sure we got what we expected");
224226 my $result =
225227 eval {
226 $io->write($data);
228 $io->raw_write($data);
227229 };
228230 ok($@, "should have croaked")
229231 and print "# $@\n";
245247 sub { print "# seek\n"; 0 },
246248 sub { print "# close\n"; 1 });
247249 my $buffer;
248 is($io->read($buffer, 10), 10, "read 10");
250 is($io->raw_read($buffer, 10), 10, "read 10");
249251 is($buffer, "xxxxxxxxxx", "read value");
250 ok($io->write("foo"), "write");
251 is($io->close, 0, "close");
252 ok($io->raw_write("foo"), "write");
253 is($io->raw_close, 0, "close");
254 }
255
256 SKIP:
257 { # fd_seek write failure
258 -c "/dev/full"
259 or skip("No /dev/full", 3);
260 open my $fh, "> /dev/full"
261 or skip("Can't open /dev/full: $!", 3);
262 my $io = Imager::io_new_fd(fileno($fh));
263 ok($io, "make fd io for /dev/full");
264 Imager::i_clear_error();
265 is($io->raw_write("test"), -1, "fail to write");
266 my $msg = Imager->_error_as_msg;
267 like($msg, qr/^write\(\) failure: /, "check error message");
268 print "# $msg\n";
269
270 # /dev/full succeeds on seek on Linux
271
272 undef $io;
273 }
274
275 SKIP:
276 { # fd_seek seek failure
277 my $seekfail = "testout/t07seekfail.dat";
278 open my $fh, "> $seekfail"
279 or skip("Can't open $seekfail: $!", 3);
280 my $io = Imager::io_new_fd(fileno($fh));
281 ok($io, "make fd io for $seekfail");
282
283 Imager::i_clear_error();
284 is($io->raw_seek(-1, SEEK_SET), -1, "shouldn't be able to seek to -1");
285 my $msg = Imager->_error_as_msg;
286 like($msg, qr/^lseek\(\) failure: /, "check error message");
287 print "# $msg\n";
288
289 undef $io;
290 close $fh;
291 unlink $seekfail;
292 }
293
294 SKIP:
295 { # fd_seek read failure
296 open my $fh, "> testout/t07writeonly.txt"
297 or skip("Can't open testout/t07writeonly.txt: $!", 3);
298 my $io = Imager::io_new_fd(fileno($fh));
299 ok($io, "make fd io for write-only");
300
301 Imager::i_clear_error();
302 my $buf;
303 is($io->raw_read($buf, 10), undef,
304 "file open for write shouldn't be readable");
305 my $msg = Imager->_error_as_msg;
306 like($msg, qr/^read\(\) failure: /, "check error message");
307 print "# $msg\n";
308
309 undef $io;
310 }
311
312 SKIP:
313 { # fd_seek eof
314 open my $fh, "> testout/t07readeof.txt"
315 or skip("Can't open testout/t07readeof.txt: $!", 5);
316 binmode $fh;
317 print $fh "test";
318 close $fh;
319 open my $fhr, "< testout/t07readeof.txt",
320 or skip("Can't open testout/t07readeof.txt: $!", 5);
321 my $io = Imager::io_new_fd(fileno($fhr));
322 ok($io, "make fd io for read eof");
323
324 Imager::i_clear_error();
325 my $buf;
326 is($io->raw_read($buf, 10), 4,
327 "10 byte read on 4 byte file should return 4");
328 my $msg = Imager->_error_as_msg;
329 is($msg, "", "should be no error message")
330 or print STDERR "# read(4) message is: $msg\n";
331
332 Imager::i_clear_error();
333 $buf = '';
334 is($io->raw_read($buf, 10), 0,
335 "10 byte read at end of 4 byte file should return 0 (eof)");
336
337 $msg = Imager->_error_as_msg;
338 is($msg, "", "should be no error message")
339 or print STDERR "# read(4), eof message is: $msg\n";
340
341 undef $io;
342 }
343
344 { # buffered I/O
345 my $data="P2\n2 2\n255\n 255 0\n0 255\n";
346 my $io = Imager::io_new_buffer($data);
347
348 my $c = $io->getc();
349
350 is($c, ord "P", "getc");
351 my $peekc = $io->peekc();
352
353 is($peekc, ord "2", "peekc");
354
355 my $peekn = $io->peekn(2);
356 is($peekn, "2\n", "peekn");
357
358 $c = $io->getc();
359 is($c, ord "2", "getc after peekc/peekn");
360
361 is($io->seek(0, SEEK_SET), "0", "seek");
362 is($io->getc, ord "P", "check we got back to the start");
363 }
364
365 { # test closecb result is propagated
366 my $success_cb = sub { 1 };
367 my $failure_cb = sub { 0 };
368
369 {
370 my $io = Imager::io_new_cb(undef, $success_cb, undef, $success_cb);
371 is($io->close(), 0, "test successful close");
372 }
373 {
374 my $io = Imager::io_new_cb(undef, $success_cb, undef, $failure_cb);
375 is($io->close(), -1, "test failed close");
376 }
377 }
378
379 { # buffered coverage/function tests
380 # some data to play with
381 my $base = pack "C*", map rand(26) + ord("a"), 0 .. 20_001;
382
383 { # buffered accessors
384 my $io = Imager::io_new_buffer($base);
385 ok($io->set_buffered(0), "set unbuffered");
386 ok(!$io->is_buffered, "verify unbuffered");
387 ok($io->set_buffered(1), "set buffered");
388 ok($io->is_buffered, "verify buffered");
389 }
390
391 { # initial i_io_read(), buffered
392 my $pos = 0;
393 my $ops = "";
394 my $work = $base;
395 my $read = sub {
396 my ($size) = @_;
397
398 my $req_size = $size;
399
400 if ($pos + $size > length $work) {
401 $size = length($work) - $pos;
402 }
403
404 my $result = substr($work, $pos, $size);
405 $pos += $size;
406 $ops .= "R$req_size>$size;";
407
408 print "# read $req_size>$size\n";
409
410 return $result;
411 };
412 my $write = sub {
413 my ($data) = @_;
414
415 substr($work, $pos, length($data), $data);
416
417 return 1;
418 };
419 {
420 my $io = Imager::io_new_cb(undef, $read, undef, undef);
421 my $buf;
422 is($io->read($buf, 1000), 1000, "read initial 1000");
423 is($buf, substr($base, 0, 1000), "check data read");
424 is($ops, "R8192>8192;", "check read op happened to buffer size");
425
426 undef $buf;
427 is($io->read($buf, 1001), 1001, "read another 1001");
428 is($buf, substr($base, 1000, 1001), "check data read");
429 is($ops, "R8192>8192;", "should be no further reads");
430
431 undef $buf;
432 is($io->read($buf, 40_000), length($base) - 2001,
433 "read the rest in one chunk");
434 is($buf, substr($base, 2001), "check the data read");
435 my $buffer_left = 8192 - 2001;
436 my $after_buffer = length($base) - 8192;
437 is($ops, "R8192>8192;R".(40_000 - $buffer_left).">$after_buffer;R21999>0;",
438 "check we tried to read the remainder");
439 }
440 {
441 # read after write errors
442 my $io = Imager::io_new_cb($write, $read, undef, undef);
443 is($io->write("test"), 4, "write 4 bytes, io in write mode");
444 is($io->read2(10), undef, "read should fail");
445 is($io->peekn(10), undef, "peekn should fail");
446 is($io->getc(), -1, "getc should fail");
447 is($io->peekc(), -1, "peekc should fail");
448 }
449 }
450
451 {
452 my $io = Imager::io_new_buffer($base);
453 print "# buffer fill check\n";
454 ok($io, "make memory io");
455 my $buf;
456 is($io->read($buf, 4096), 4096, "read 4k");
457 is($buf, substr($base, 0, 4096), "check data is correct");
458
459 # peek a bit
460 undef $buf;
461 is($io->peekn(5120), substr($base, 4096, 5120),
462 "peekn() 5120, which should exceed the buffer, and only read the left overs");
463 }
464
465 { # initial peekn
466 my $io = Imager::io_new_buffer($base);
467 is($io->peekn(10), substr($base, 0, 10),
468 "make sure initial peekn() is sane");
469 is($io->read2(10), substr($base, 0, 10),
470 "and that reading 10 gets the expected data");
471 }
472
473 { # oversize peekn
474 my $io = Imager::io_new_buffer($base);
475 is($io->peekn(10_000), substr($base, 0, 8192),
476 "peekn() larger than buffer should return buffer-size bytes");
477 }
478
479 { # small peekn then large peekn with a small I/O back end
480 # this might happen when reading from a socket
481 my $work = $base;
482 my $pos = 0;
483 my $ops = '';
484 my $reader = sub {
485 my ($size) = @_;
486
487 my $req_size = $size;
488 # do small reads, to trigger a possible bug
489 if ($size > 10) {
490 $size = 10;
491 }
492
493 if ($pos + $size > length $work) {
494 $size = length($work) - $pos;
495 }
496
497 my $result = substr($work, $pos, $size);
498 $pos += $size;
499 $ops .= "R$req_size>$size;";
500
501 print "# read $req_size>$size\n";
502
503 return $result;
504 };
505 my $io = Imager::io_new_cb(undef, $reader, undef, undef);
506 ok($io, "small reader io");
507 is($io->peekn(25), substr($base, 0, 25), "peek 25");
508 is($ops, "R8192>10;R8182>10;R8172>10;",
509 "check we got the raw calls expected");
510 is($io->peekn(65), substr($base, 0, 65), "peek 65");
511 is($ops, "R8192>10;R8182>10;R8172>10;R8162>10;R8152>10;R8142>10;R8132>10;",
512 "check we got the raw calls expected");
513 }
514 for my $buffered (1, 0) { # peekn followed by errors
515 my $buffered_desc = $buffered ? "buffered" : "unbuffered";
516 my $read = 0;
517 my $base = "abcdef";
518 my $pos = 0;
519 my $reader = sub {
520 my $size = shift;
521 my $req_size = $size;
522 if ($pos + $size > length $base) {
523 $size = length($base) - $pos;
524 }
525 # error instead of eof
526 if ($size == 0) {
527 print "# read $req_size>error\n";
528 return;
529 }
530 my $result = substr($base, $pos, $size);
531 $pos += $size;
532
533 print "# read $req_size>$size\n";
534
535 return $result;
536 };
537 my $io = Imager::io_new_cb(undef, $reader, undef, undef);
538 ok($io, "make $buffered_desc cb with error after 6 bytes");
539 is($io->peekn(5), "abcde",
540 "peekn until just before error ($buffered_desc)");
541 is($io->peekn(6), "abcdef", "peekn until error ($buffered_desc)");
542 is($io->peekn(7), "abcdef", "peekn past error ($buffered_desc)");
543 ok(!$io->error,
544 "should be no error indicator, since data buffered ($buffered_desc)");
545 ok(!$io->eof,
546 "should be no eof indicator, since data buffered ($buffered_desc)");
547
548 # consume it
549 is($io->read2(6), "abcdef", "consume the buffer ($buffered_desc)");
550 is($io->peekn(10), undef,
551 "peekn should get an error indicator ($buffered_desc)");
552 ok($io->error, "should be an error state ($buffered_desc)");
553 ok(!$io->eof, "but not eof ($buffered_desc)");
554 }
555 { # peekn on an empty file
556 my $io = Imager::io_new_buffer("");
557 is($io->peekn(10), "", "peekn on empty source");
558 ok($io->eof, "should be in eof state");
559 ok(!$io->error, "but not error");
560 }
561 { # peekn on error source
562 my $io = Imager::io_new_cb(undef, sub { return; }, undef, undef);
563 is($io->peekn(10), undef, "peekn on empty source");
564 ok($io->error, "should be in error state");
565 ok(!$io->eof, "but not eof");
566 }
567 { # peekn on short source
568 my $io = Imager::io_new_buffer("abcdef");
569 is($io->peekn(4), "abcd", "peekn 4 on 6 byte source");
570 is($io->peekn(10), "abcdef", "followed by peekn 10 on 6 byte source");
571 is($io->peekn(10), "abcdef", "and again, now eof is set");
572 }
573 { # peekn(0)
574 Imager::i_clear_error();
575 my $io = Imager::io_new_buffer("abcdef");
576 is($io->peekn(0), undef, "peekn 0 on 6 byte source");
577 my $msg = Imager->_error_as_msg;
578 is($msg, "peekn size must be positive");
579 }
580 { # getc through a whole file (buffered)
581 my $io = Imager::io_new_buffer($base);
582 my $out = '';
583 while ((my $c = $io->getc()) != -1) {
584 $out .= chr($c);
585 }
586 is($out, $base, "getc should return the file byte by byte (buffered)");
587 is($io->getc, -1, "another getc after eof should fail too");
588 ok($io->eof, "should be marked eof");
589 ok(!$io->error, "shouldn't be marked in error");
590 }
591 { # getc through a whole file (unbuffered)
592 my $io = Imager::io_new_buffer($base);
593 $io->set_buffered(0);
594 my $out = '';
595 while ((my $c = $io->getc()) != -1) {
596 $out .= chr($c);
597 }
598 is($out, $base, "getc should return the file byte by byte (unbuffered)");
599 is($io->getc, -1, "another getc after eof should fail too");
600 ok($io->eof, "should be marked eof");
601 ok(!$io->error, "shouldn't be marked in error");
602 }
603 { # buffered getc with an error
604 my $io = Imager::io_new_cb(undef, sub { return; }, undef, undef);
605 is($io->getc, -1, "buffered getc error");
606 ok($io->error, "io marked in error");
607 ok(!$io->eof, "but not eof");
608 }
609 { # unbuffered getc with an error
610 my $io = Imager::io_new_cb(undef, sub { return; }, undef, undef);
611 $io->set_buffered(0);
612 is($io->getc, -1, "unbuffered getc error");
613 ok($io->error, "io marked in error");
614 ok(!$io->eof, "but not eof");
615 }
616 { # initial peekc - buffered
617 my $io = Imager::io_new_buffer($base);
618 my $c = $io->peekc;
619 is($c, ord($base), "buffered peekc matches");
620 is($io->peekc, $c, "duplicate peekc matchess");
621 }
622 { # initial peekc - unbuffered
623 my $io = Imager::io_new_buffer($base);
624 $io->set_buffered(0);
625 my $c = $io->peekc;
626 is($c, ord($base), "unbuffered peekc matches");
627 is($io->peekc, $c, "duplicate peekc matchess");
628 }
629 { # initial peekc eof - buffered
630 my $io = Imager::io_new_cb(undef, sub { "" }, undef, undef);
631 my $c = $io->peekc;
632 is($c, -1, "buffered eof peekc is -1");
633 is($io->peekc, $c, "duplicate matches");
634 ok($io->eof, "io marked eof");
635 ok(!$io->error, "but not error");
636 }
637 { # initial peekc eof - unbuffered
638 my $io = Imager::io_new_cb(undef, sub { "" }, undef, undef);
639 $io->set_buffered(0);
640 my $c = $io->peekc;
641 is($c, -1, "buffered eof peekc is -1");
642 is($io->peekc, $c, "duplicate matches");
643 ok($io->eof, "io marked eof");
644 ok(!$io->error, "but not error");
645 }
646 { # initial peekc error - buffered
647 my $io = Imager::io_new_cb(undef, sub { return; }, undef, undef);
648 my $c = $io->peekc;
649 is($c, -1, "buffered error peekc is -1");
650 is($io->peekc, $c, "duplicate matches");
651 ok($io->error, "io marked error");
652 ok(!$io->eof, "but not eof");
653 }
654 { # initial peekc error - unbuffered
655 my $io = Imager::io_new_cb(undef, sub { return; }, undef, undef);
656 $io->set_buffered(0);
657 my $c = $io->peekc;
658 is($c, -1, "unbuffered error peekc is -1");
659 is($io->peekc, $c, "duplicate matches");
660 ok($io->error, "io marked error");
661 ok(!$io->eof, "but not eof");
662 }
663 { # initial putc
664 my $io = Imager::io_new_bufchain();
665 is($io->putc(ord "A"), ord "A", "initial putc buffered");
666 is($io->close, 0, "close it");
667 is(Imager::io_slurp($io), "A", "check it was written");
668 }
669 { # initial putc - unbuffered
670 my $io = Imager::io_new_bufchain();
671 $io->set_buffered(0);
672 is($io->putc(ord "A"), ord "A", "initial putc unbuffered");
673 is($io->close, 0, "close it");
674 is(Imager::io_slurp($io), "A", "check it was written");
675 }
676 { # putc unbuffered with error
677 my $io = Imager::io_new_cb(undef, undef, undef, undef);
678 $io->set_buffered(0);
679 is($io->putc(ord "A"), -1, "initial putc unbuffered error");
680 ok($io->error, "io in error");
681 is($io->putc(ord "B"), -1, "still in error");
682 }
683 { # writes while in read state
684 my $io = Imager::io_new_cb(sub { 1 }, sub { return "AA" }, undef, undef);
685 is($io->getc, ord "A", "read to setup read buffer");
686 is($io->putc(ord "B"), -1, "putc should fail");
687 is($io->write("test"), -1, "write should fail");
688 }
689 { # buffered putc error handling
690 # tests the check for error state in the buffered putc code
691 my $io = Imager::io_new_cb(undef, undef, undef, undef);
692 $io->putc(ord "A");
693 ok(!$io->flush, "flush should fail");
694 ok($io->error, "should be in error state");
695 is($io->putc(ord "B"), -1, "check for error");
696 }
697 { # buffered putc flush error handling
698 # test handling of flush failure and of the error state resulting
699 # from that
700 my $io = Imager::io_new_cb(undef, undef, undef, undef);
701 my $i = 0;
702 while (++$i < 100_000 && $io->putc(ord "A") == ord "A") {
703 # until we have to flush and fail doing do
704 }
705 is($i, 8193, "should have failed on 8193rd byte");
706 ok($io->error, "should be in error state");
707 is($io->putc(ord "B"), -1, "next putc should fail");
708 }
709 { # buffered write flush error handling
710 # test handling of flush failure and of the error state resulting
711 # from that
712 my $io = Imager::io_new_cb(undef, undef, undef, undef);
713 my $i = 0;
714 while (++$i < 100_000 && $io->write("A") == 1) {
715 # until we have to flush and fail doing do
716 }
717 is($i, 8193, "should have failed on 8193rd byte");
718 ok($io->error, "should be in error state");
719 is($io->write("B"), -1, "next write should fail");
720 }
721 { # buffered read error
722 my $io = Imager::io_new_cb(undef, undef, undef, undef);
723 is($io->read2(10), undef, "initial read returning error");
724 ok($io->error, "should be in error state");
725 }
726 { # unbuffered read error
727 my $io = Imager::io_new_cb(undef, undef, undef, undef);
728 $io->set_buffered(0);
729 is($io->read2(10), undef, "initial read returning error");
730 ok($io->error, "should be in error state");
731 }
732 { # unbuffered write error
733 my $count = 0;
734 my $io = Imager::io_new_cb(sub { return $count++; }, undef, undef, undef);
735 $io->set_buffered(0);
736 is($io->write("A"), -1, "unbuffered write failure");
737 ok($io->error, "should be in error state");
738 is($io->write("BC"), -1, "should still fail");
739 }
740 { # buffered write + large write
741 my $io = Imager::io_new_bufchain();
742 is($io->write(substr($base, 0, 4096)), 4096,
743 "should be buffered");
744 is($io->write(substr($base, 4096)), length($base) - 4096,
745 "large write, should fill buffer and fall back to direct write");
746 is($io->close, 0, "close it");
747 is(Imager::io_slurp($io), $base, "make sure the data is correct");
748 }
749 { # initial large write with failure
750 # tests error handling for the case where we bypass the buffer
751 # when the write is too large to fit
752 my $io = Imager::io_new_cb(undef, undef, undef, undef);
753 ok($io->flush, "flush with nothing buffered should succeed");
754 is($io->write($base), -1, "large write failure");
755 ok($io->error, "should be in error state");
756 is($io->close, -1, "should fail to close");
757 }
758 { # write that causes a flush then fills the buffer a bit
759 my $io = Imager::io_new_bufchain();
760 is($io->write(substr($base, 0, 6000)), 6000, "fill the buffer a bit");
761 is($io->write(substr($base, 6000, 4000)), 4000,
762 "cause it to flush and then fill some more");
763 is($io->write(substr($base, 10000)), length($base)-10000,
764 "write out the rest of our test data");
765 is($io->close, 0, "close the stream");
766 is(Imager::io_slurp($io), $base, "make sure the data is right");
767 }
768 { # failure on flush on close
769 my $io = Imager::io_new_cb(undef, undef, undef, undef);
770 is($io->putc(ord "A"), ord "A", "something in the buffer");
771 ok(!$io->error, "should be no error yet");
772 is($io->close, -1, "close should failure due to flush error");
773 }
774 { # seek failure
775 my $io = Imager::io_new_cb(undef, undef, undef, undef);
776 is($io->seek(0, SEEK_SET), -1, "seek failure");
777 }
778 { # read a little and seek
779 my $io = Imager::io_new_buffer($base);
780 is($io->getc, ord $base, "read one");
781 is($io->getc, ord substr($base, 1, 1), "read another");
782 is($io->seek(-1, SEEK_CUR), 1, "seek relative back to origin+1");
783 is($io->getc, ord substr($base, 1, 1), "read another again");
784 }
785 { # seek with failing flush
786 my $io = Imager::io_new_cb(undef, undef, undef, undef);
787 is($io->putc(ord "A"), ord "A", "write one");
788 ok(!$io->error, "not in error mode (yet)");
789 is($io->seek(0, SEEK_SET), -1, "seek failure due to flush");
790 ok($io->error, "in error mode");
791 }
792 { # gets()
793 my $data = "test1\ntest2\ntest3";
794 my $io = Imager::io_new_buffer($data);
795 is($io->gets(6), "test1\n", "gets(6)");
796 is($io->gets(5), "test2", "gets(5) (short for the line)");
797 is($io->gets(10), "\n", "gets(10) the rest of the line (the newline)");
798 is($io->gets(), "test3", "gets(default) unterminated line");
799 }
800 { # more gets()
801 my $data = "test1\ntest2\ntest3";
802 my $io = Imager::io_new_buffer($data);
803 is($io->gets(6, ord("1")), "test1", "gets(6) (line terminator 1)");
804 is($io->gets(6, ord("2")), "\ntest2", "gets(6) (line terminator 2)");
805 is($io->gets(6, ord("3")), "\ntest3", "gets(6) (line terminator 3)");
806 is($io->getc, -1, "should be eof");
807 }
252808 }
253809
254810 Imager->close_log;
00 #!perl -w
11 use strict;
2 use Test::More tests => 47;
2 use Test::More tests => 53;
33 use Imager qw(:all);
4 use Imager::Test qw/is_color3 is_color4/;
4 use Imager::Test qw/is_color3 is_color4 test_image test_image_mono/;
55
66 -d "testout" or mkdir "testout";
77
165165 open RAW, "< testout/t103_empty.raw"
166166 or die "Cannot open testout/t103_empty.raw: $!";
167167 my $im = Imager->new(xsize => 50, ysize=>50);
168 ok(!$im->write(fh => \*RAW, type => 'raw'),
168 ok(!$im->write(fh => \*RAW, type => 'raw', buffered => 0),
169169 "write to open for read handle");
170170 cmp_ok($im->errstr, '=~', '^Could not write to file: write\(\) failure',
171171 "check error message");
269269 "check last channel zeroed");
270270 }
271271
272 {
273 my @ims = ( basic => test_image(), mono => test_image_mono() );
274 push @ims, masked => test_image()->masked();
275
276 my $fail_close = sub {
277 Imager::i_push_error(0, "synthetic close failure");
278 return 0;
279 };
280
281 while (my ($type, $im) = splice(@ims, 0, 2)) {
282 my $io = Imager::io_new_cb(sub { 1 }, undef, undef, $fail_close);
283 ok(!$im->write(io => $io, type => "raw"),
284 "write $type image with a failing close handler");
285 like($im->errstr, qr/synthetic close failure/,
286 "check error message");
287 }
288 }
289
272290 Imager->close_log;
273291
274292 unless ($ENV{IMAGER_KEEP_FILES}) {
00 #!perl -w
11 use Imager ':all';
2 use Test::More tests => 195;
2 use Test::More tests => 205;
33 use strict;
4 use Imager::Test qw(test_image_raw test_image_16 is_color3 is_color1 is_image);
4 use Imager::Test qw(test_image_raw test_image_16 is_color3 is_color1 is_image test_image_named);
5
6 $| = 1;
57
68 -d "testout" or mkdir "testout";
79
6466 "compare written and read greyscale images");
6567
6668 my $ooim = Imager->new;
67 ok($ooim->read(file=>"testimg/simple.pbm"), "read simple pbm, via OO");
69 ok($ooim->read(file=>"testimg/simple.pbm"), "read simple pbm, via OO")
70 or print "# ", $ooim->errstr, "\n";
6871
6972 check_gray(Imager::i_get_pixel($ooim->{IMG}, 0, 0), 0);
7073 check_gray(Imager::i_get_pixel($ooim->{IMG}, 0, 1), 255);
232235 ok($im->write(file=>"testout/t104_alpha.ppm", type=>'pnm'),
233236 "should succeed writing 4 channel image");
234237 my $imread = Imager->new;
235 ok($imread->read(file => 'testout/t104_alpha.ppm'), "read it back");
238 ok($imread->read(file => 'testout/t104_alpha.ppm'), "read it back")
239 or print "# ", $imread->errstr, "\n";
236240 is_color3($imread->getpixel('x' => 0, 'y' => 0), 0, 0, 0,
237241 "check transparent became black");
238242 is_color3($imread->getpixel('x' => 8, 'y' => 0), 255, 224, 192,
593597 }
594598 }
595599
596 Imager->close_log;
597
598600 { # image too large handling
599601 {
600602 ok(!Imager->new(file => "testimg/toowide.ppm", filetype => "pnm"),
610612 }
611613 }
612614
615 { # make sure close is checked for each image type
616 my $fail_close = sub {
617 Imager::i_push_error(0, "synthetic close failure");
618 return 0;
619 };
620
621 for my $type (qw(basic basic16 gray gray16 mono)) {
622 my $im = test_image_named($type);
623 my $io = Imager::io_new_cb(sub { 1 }, undef, undef, $fail_close);
624 ok(!$im->write(io => $io, type => "pnm"),
625 "write $type image with a failing close handler");
626 like($im->errstr, qr/synthetic close failure/,
627 "check error message");
628 }
629 }
630
631 Imager->close_log;
632
613633 unless ($ENV{IMAGER_KEEP_FILES}) {
614634 unlink "testout/t104ppm.log";
615635 unlink map "testout/$_", @files;
00 #!perl -w
11 use strict;
2 use Test::More tests => 213;
2 use Test::More tests => 215;
33 use Imager qw(:all);
44 use Imager::Test qw(test_image_raw is_image is_color3 test_image);
55
612612 $im->read(file => "testimg/$file")
613613 or die "Cannot read $file: ", $im->errstr;
614614
615 ok(!$im->write(type => 'bmp', callback => limited_write($limit),
616 maxbuffer => 1),
615 my $io = Imager::io_new_cb(limited_write($limit), undef, undef, undef, 1);
616 $io->set_buffered(0);
617 print "# writing with limit of $limit\n";
618 ok(!$im->write(type => 'bmp', io => $io),
617619 "$test_index - $desc: write should fail");
618620 is($im->errstr, $error, "$test_index - $desc: check error message");
619621
663665 ok($im->write(data => \$data, type => 'bmp'), "write using OO");
664666 my $size = unpack("V", substr($data, 34, 4));
665667 is($size, 67800, "check data size");
668 }
669
670 { # check close failures are handled correctly
671 my $im = test_image();
672 my $fail_close = sub {
673 Imager::i_push_error(0, "synthetic close failure");
674 return 0;
675 };
676 ok(!$im->write(type => "bmp", callback => sub { 1 },
677 closecb => $fail_close),
678 "check failing close fails");
679 like($im->errstr, qr/synthetic close failure/,
680 "check error message");
666681 }
667682
668683 Imager->close_log;
00 #!perl -w
11 use Imager qw(:all);
22 use strict;
3 use Test::More tests=>66;
4 use Imager::Test qw(is_color4 is_image);
3 use Test::More tests=>68;
4 use Imager::Test qw(is_color4 is_image test_image);
55
66 -d "testout" or mkdir "testout";
77
231231 }
232232 }
233233
234 { # check close failures are handled correctly
235 my $im = test_image();
236 my $fail_close = sub {
237 Imager::i_push_error(0, "synthetic close failure");
238 return 0;
239 };
240 ok(!$im->write(type => "tga", callback => sub { 1 },
241 closecb => $fail_close),
242 "check failing close fails");
243 like($im->errstr, qr/synthetic close failure/,
244 "check error message");
245 }
246
234247 sub write_test {
235248 my ($im, $filename, $wierdpack, $compress, $idstring) = @_;
236249 local *FH;
00 #!perl -w
11 use strict;
2 use Test::More tests => 156;
2 use Test::More tests => 157;
33
44 use Imager ':handy';
55 use Imager::Fill;
637637 }
638638 }
639639
640 { # RT 71309
641 my $fount = Imager::Fountain->simple(colors => [ '#804041', '#804041' ],
642 positions => [ 0, 1 ]);
643 my $im = Imager->new(xsize => 40, ysize => 40);
644 $im->box(filled => 1, color => '#804040');
645 my $fill = Imager::Fill->new
646 (
647 combine => 0,
648 fountain => "linear",
649 segments => $fount,
650 xa => 0, ya => 0,
651 xb => 40, yb => 40,
652 );
653 $im->polygon(fill => $fill,
654 points =>
655 [
656 [ 0, 0 ],
657 [ 40, 20 ],
658 [ 20, 40 ],
659 ]
660 );
661 # the bug magnified the differences between the source and destination
662 # color, blending between the background and fill colors here only allows
663 # for those 2 colors in the result.
664 # with the bug extra colors appeared along the edge of the polygon.
665 is($im->getcolorcount, 2, "only original and fill color");
666 }
667
640668 sub color_close {
641669 my ($c1, $c2) = @_;
642670
99
1010 # Change 1..1 below to 1..last_test_to_print .
1111 # (It may become useful if the test is moved to ./t subdirectory.)
12 use Test::More tests => 12;
12 use Test::More tests => 16;
1313
1414 BEGIN { use_ok('Imager') };
15
16 BEGIN {
17 require Imager::Test;
18 Imager::Test->import(qw(isnt_image));
19 }
1520
1621 -d "testout" or mkdir "testout";
1722
2732 SKIP:
2833 {
2934 $Imager::formats{"tt"} && -f $fontname_tt
30 or skip("FT1.x missing or disabled", 10);
35 or skip("FT1.x missing or disabled", 14);
3136
3237 my $img=Imager->new(xsize=>300, ysize=>100) or die "$Imager::ERRSTR\n";
3338
7277 my @has_chars = $font->has_chars(string=>"\x01A");
7378 ok(!$has_chars[0], "has_chars list 0");
7479 ok($has_chars[1], "has_chars list 1");
80
81 { # RT 71469
82 my $font1 = Imager::Font->new(file => $fontname_tt, type => "tt");
83 my $font2 = Imager::Font::Truetype->new(file => $fontname_tt);
84
85 for my $font ($font1, $font2) {
86 print "# ", join(",", $font->{color}->rgba), "\n";
87
88 my $im = Imager->new(xsize => 20, ysize => 20, channels => 4);
89
90 ok($im->string(text => "T", font => $font, y => 15),
91 "draw with default color")
92 or print "# ", $im->errstr, "\n";
93 my $work = Imager->new(xsize => 20, ysize => 20);
94 my $cmp = $work->copy;
95 $work->rubthrough(src => $im);
96 isnt_image($work, $cmp, "make sure something was drawn");
97 }
98 }
7599 }
76100
77101 ok(1, "end");
00 #!perl -w
11 use strict;
22 use Imager qw(:handy);
3 use Test::More tests => 113;
3 use Test::More tests => 116;
44
55 -d "testout" or mkdir "testout";
66
2121 # this one's kind of cool
2222 test($imbase, {type=>'conv', coef=>[ 0.3, 1, 0.3, ], },
2323 'testout/t61_conv_blur.ppm');
24
25 {
26 my $work = $imbase->copy;
27 ok(!Imager::i_conv($work->{IMG}, []), "conv should fail with empty array");
28 ok(!$work->filter(type => 'conv', coef => []),
29 "check the conv OO intergave too");
30 is($work->errstr, "there must be at least one coefficient",
31 "check conv error message");
32 }
2433
2534 {
2635 my $work8 = $imbase->copy;
1717
1818 -d "testout" or mkdir "testout";
1919
20 plan tests => 9;
20 plan tests => 16;
2121 require Inline;
2222 Inline->import(with => 'Imager');
2323 Inline->import("FORCE"); # force rebuild
24 #Inline->import(C => Config => OPTIMIZE => "-g");
2425
2526 Inline->bind(C => <<'EOS');
2627 #include <math.h>
232233 return im;
233234 }
234235
236 void
237 io_fd(int fd) {
238 Imager::IO io = io_new_fd(fd);
239 i_io_write(io, "test", 4);
240 i_io_close(io);
241 io_glue_destroy(io);
242 }
243
244 int
245 io_bufchain_test() {
246 Imager::IO io = io_new_bufchain();
247 unsigned char *result;
248 size_t size;
249 if (i_io_write(io, "test2", 5) != 5) {
250 fprintf(stderr, "write failed\n");
251 return 0;
252 }
253 if (!i_io_flush(io)) {
254 fprintf(stderr, "flush failed\n");
255 return 0;
256 }
257 if (i_io_close(io) != 0) {
258 fprintf(stderr, "close failed\n");
259 return 0;
260 }
261 size = io_slurp(io, &result);
262 if (size != 5) {
263 fprintf(stderr, "wrong size\n");
264 return 0;
265 }
266 if (memcmp(result, "test2", 5)) {
267 fprintf(stderr, "data mismatch\n");
268 return 0;
269 }
270 if (i_io_seek(io, 0, 0) != 0) {
271 fprintf(stderr, "seek failure\n");
272 return 0;
273 }
274 myfree(result);
275 io_glue_destroy(io);
276
277 return 1;
278 }
279
280 const char *
281 io_buffer_test(SV *in) {
282 STRLEN len;
283 const char *in_str = SvPV(in, len);
284 static char buf[100];
285 Imager::IO io = io_new_buffer(in_str, len, NULL, NULL);
286 ssize_t read_size;
287
288 read_size = i_io_read(io, buf, sizeof(buf)-1);
289 io_glue_destroy(io);
290 if (read_size < 0 || read_size >= sizeof(buf)) {
291 return "";
292 }
293
294 buf[read_size] = '\0';
295
296 return buf;
297 }
298
299 const char *
300 io_peekn_test(SV *in) {
301 STRLEN len;
302 const char *in_str = SvPV(in, len);
303 static char buf[100];
304 Imager::IO io = io_new_buffer(in_str, len, NULL, NULL);
305 ssize_t read_size;
306
307 read_size = i_io_peekn(io, buf, sizeof(buf)-1);
308 io_glue_destroy(io);
309 if (read_size < 0 || read_size >= sizeof(buf)) {
310 return "";
311 }
312
313 buf[read_size] = '\0';
314
315 return buf;
316 }
317
318 const char *
319 io_gets_test(SV *in) {
320 STRLEN len;
321 const char *in_str = SvPV(in, len);
322 static char buf[100];
323 Imager::IO io = io_new_buffer(in_str, len, NULL, NULL);
324 ssize_t read_size;
325
326 read_size = i_io_gets(io, buf, sizeof(buf), 's');
327 io_glue_destroy(io);
328 if (read_size < 0 || read_size >= sizeof(buf)) {
329 return "";
330 }
331
332 return buf;
333 }
334
335 int
336 io_getc_test(SV *in) {
337 STRLEN len;
338 const char *in_str = SvPV(in, len);
339 static char buf[100];
340 Imager::IO io = io_new_buffer(in_str, len, NULL, NULL);
341 int result;
342
343 result = i_io_getc(io);
344 io_glue_destroy(io);
345
346 return result;
347 }
348
349 int
350 io_peekc_test(SV *in) {
351 STRLEN len;
352 const char *in_str = SvPV(in, len);
353 static char buf[100];
354 Imager::IO io = io_new_buffer(in_str, len, NULL, NULL);
355 int result;
356
357 i_io_set_buffered(io, 0);
358
359 result = i_io_peekc(io);
360 io_glue_destroy(io);
361
362 return result;
363 }
364
235365 EOS
236366
237367 my $im = Imager->new(xsize=>50, ysize=>50);
265395 is ($imb->REFCNT, $im2b->REFCNT,
266396 "check refcnt of imager object hash between normal and typemap generated");
267397 }
398
399 SKIP:
400 {
401 use IO::File;
402 my $fd_filename = "testout/t82fd.txt";
403 {
404 my $fh = IO::File->new($fd_filename, "w")
405 or skip("Can't create file: $!", 1);
406 io_fd(fileno($fh));
407 $fh->close;
408 }
409 {
410 my $fh = IO::File->new($fd_filename, "r")
411 or skip("Can't open file: $!", 1);
412 my $data = <$fh>;
413 is($data, "test", "make sure data written to fd");
414 }
415 unlink $fd_filename;
416 }
417
418 ok(io_bufchain_test(), "check bufchain functions");
419
420 is(io_buffer_test("test3"), "test3", "check io_new_buffer() and i_io_read");
421
422 is(io_peekn_test("test5"), "test5", "check i_io_peekn");
423
424 is(io_gets_test("test"), "tes", "check i_io_gets()");
425
426 is(io_getc_test("ABC"), ord "A", "check i_io_getc(_imp)?");
427
428 is(io_getc_test("XYZ"), ord "X", "check i_io_peekc(_imp)?");
22 use lib 't';
33 use Test::More;
44 use ExtUtils::Manifest qw(maniread);
5 #sub Pod::Coverage::TRACE_ALL() { 1 }
56 eval "use Test::Pod::Coverage 1.08;";
67 # 1.08 required for coverage_class support
78 plan skip_all => "Test::Pod::Coverage 1.08 required for POD coverage" if $@;
2324 );
2425 my @trustme = ( '^open$', );
2526
26 plan tests => 19;
27 plan tests => 20;
2728
2829 {
2930 pod_coverage_ok('Imager', { also_private => \@private,
4950 pod_coverage_ok('Imager::Regops');
5051 pod_coverage_ok('Imager::Transform');
5152 pod_coverage_ok('Imager::Test');
53 pod_coverage_ok('Imager::IO',
54 {
55 pod_from => "lib/Imager/IO.pod",
56 coverage_class => "Pod::Coverage::Imager",
57 module => "Imager",
58 });
5259 }
5360
5461 {
+18
-19
tga.c less more
432432 tga_source_read(tga_source *s, unsigned char *buf, size_t pixels) {
433433 int cp = 0, j, k;
434434 if (!s->compressed) {
435 if (s->ig->readcb(s->ig, buf, pixels*s->bytepp) != pixels*s->bytepp) return 0;
435 if (i_io_read(s->ig, buf, pixels*s->bytepp) != pixels*s->bytepp) return 0;
436436 return 1;
437437 }
438438
441441 if (s->len == 0) s->state = NoInit;
442442 switch (s->state) {
443443 case NoInit:
444 if (s->ig->readcb(s->ig, &s->hdr, 1) != 1) return 0;
444 if (i_io_read(s->ig, &s->hdr, 1) != 1) return 0;
445445
446446 s->len = (s->hdr &~(1<<7))+1;
447447 s->state = (s->hdr & (1<<7)) ? Rle : Raw;
451451 printf("%04d %s: %d\n", cnt++, s->state==Rle?"RLE":"RAW", s->len);
452452 */
453453 }
454 if (s->state == Rle && s->ig->readcb(s->ig, s->cval, s->bytepp) != s->bytepp) return 0;
454 if (s->state == Rle && i_io_read(s->ig, s->cval, s->bytepp) != s->bytepp) return 0;
455455
456456 break;
457457 case Rle:
463463 break;
464464 case Raw:
465465 ml = i_min(s->len, pixels-cp);
466 if (s->ig->readcb(s->ig, buf+cp*s->bytepp, ml*s->bytepp) != ml*s->bytepp) return 0;
466 if (i_io_read(s->ig, buf+cp*s->bytepp, ml*s->bytepp) != ml*s->bytepp) return 0;
467467 cp += ml;
468468 s->len -= ml;
469469 break;
494494 int cp = 0;
495495
496496 if (!s->compressed) {
497 if (s->ig->writecb(s->ig, buf, pixels*s->bytepp) != pixels*s->bytepp) return 0;
497 if (i_io_write(s->ig, buf, pixels*s->bytepp) != pixels*s->bytepp) return 0;
498498 return 1;
499499 }
500500
505505 while(tlen) {
506506 unsigned char clen = (tlen>128) ? 128 : tlen;
507507 clen--;
508 if (s->ig->writecb(s->ig, &clen, 1) != 1) return 0;
508 if (i_io_write(s->ig, &clen, 1) != 1) return 0;
509509 clen++;
510 if (s->ig->writecb(s->ig, buf+cp*s->bytepp, clen*s->bytepp) != clen*s->bytepp) return 0;
510 if (i_io_write(s->ig, buf+cp*s->bytepp, clen*s->bytepp) != clen*s->bytepp) return 0;
511511 tlen -= clen;
512512 cp += clen;
513513 }
517517 while (tlen) {
518518 unsigned char clen = (tlen>128) ? 128 : tlen;
519519 clen = (clen - 1) | 0x80;
520 if (s->ig->writecb(s->ig, &clen, 1) != 1) return 0;
520 if (i_io_write(s->ig, &clen, 1) != 1) return 0;
521521 clen = (clen & ~0x80) + 1;
522 if (s->ig->writecb(s->ig, buf+cp*s->bytepp, s->bytepp) != s->bytepp) return 0;
522 if (i_io_write(s->ig, buf+cp*s->bytepp, s->bytepp) != s->bytepp) return 0;
523523 tlen -= clen;
524524 cp += clen;
525525 }
557557 palbsize = colourmaplength*bytepp;
558558 palbuf = mymalloc(palbsize);
559559
560 if (ig->readcb(ig, palbuf, palbsize) != palbsize) {
560 if (i_io_read(ig, palbuf, palbsize) != palbsize) {
561561 i_push_error(errno, "could not read targa colourmap");
562562 return 0;
563563 }
599599 color_pack(palbuf+i*bytepp, bitspp, &val);
600600 }
601601
602 if (ig->writecb(ig, palbuf, palbsize) != palbsize) {
602 if (i_io_write(ig, palbuf, palbsize) != palbsize) {
603603 i_push_error(errno, "could not write targa colourmap");
604604 return 0;
605605 }
640640
641641 mm_log((1,"i_readtga(ig %p, length %d)\n", ig, length));
642642
643 io_glue_commit_types(ig);
644
645 if (ig->readcb(ig, &headbuf, 18) != 18) {
643 if (i_io_read(ig, &headbuf, 18) != 18) {
646644 i_push_error(errno, "could not read targa header");
647645 return NULL;
648646 }
665663 if (header.idlength) {
666664 /* max of 256, so this is safe */
667665 idstring = mymalloc(header.idlength+1);
668 if (ig->readcb(ig, idstring, header.idlength) != header.idlength) {
666 if (i_io_read(ig, idstring, header.idlength) != header.idlength) {
669667 i_push_error(errno, "short read on targa idstring");
670668 return NULL;
671669 }
897895
898896 tga_header_pack(&header, headbuf);
899897
900 if (ig->writecb(ig, &headbuf, sizeof(headbuf)) != sizeof(headbuf)) {
898 if (i_io_write(ig, &headbuf, sizeof(headbuf)) != sizeof(headbuf)) {
901899 i_push_error(errno, "could not write targa header");
902900 return 0;
903901 }
904902
905903 if (idlen) {
906 if (ig->writecb(ig, idstring, idlen) != idlen) {
904 if (i_io_write(ig, idstring, idlen) != idlen) {
907905 i_push_error(errno, "could not write targa idstring");
908906 return 0;
909907 }
921919 if (!tga_palette_write(ig, img, bitspp, i_colorcount(img))) return 0;
922920
923921 if (!img->virtual && !dest.compressed) {
924 if (ig->writecb(ig, img->idata, img->bytes) != img->bytes) {
922 if (i_io_write(ig, img->idata, img->bytes) != img->bytes) {
925923 i_push_error(errno, "could not write targa image data");
926924 return 0;
927925 }
950948 myfree(vals);
951949 }
952950
953 ig->closecb(ig);
951 if (i_io_close(ig))
952 return 0;
954953
955954 return 1;
956955 }
2525 Imager T_IMAGER_FULL_IMAGE
2626
2727 off_t T_OFF_T
28
29 # STRLEN isn't in the default typemap in older perls
30 STRLEN T_UV
2831
2932 #############################################################################
3033 INPUT