Imager
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
options.
Imager 1.014 - 28 Apr 2022
============
Bug fixes:
- fix failed to build on non-threaded perls.
https://github.com/tonycoz/imager/issues/472
- when writing a paletted image with an alpha channel to PNG only
set the tRNS chunk if the image has transparent colours. With
older libpng this could add an erroneous tRNS chunk (or possibly
undefined behaviour if I understand the libpng code).
https://github.com/tonycoz/imager/issues/459
Features:
- Imager::Color and Imager::Color::Float objects can now be created
from CSS style rgb(...) strings.
https://github.com/tonycoz/imager/issues/463
Changes.old view on Meta::CPAN
0.28 Tue Jan 4 05:25:58 2000 > CPAN release <
- Only fixes to truetype test and transformation tests.
Thanks to schinder of cpan testers for testing and reporting.
0.29 Tue Jan 4 21:49:57 2000 > CPAN release <
- fixes to get rid of warnings under pre 5.005,
Fixed broken preproccessor directives to work on non gnu
compilers. Fixed DSO test on HPUX - both code errors and
HPUX creates .sl instead of .so so the tests were failing.
0.30 Sun Jan 7 05:00:06 2000 > Bunch of Alpha releases <
- An attempt to automate installation.
0.31 Sat Jan 15 03:58:29 2000 > Fixes fixes fixes <
- Fixed a bug pointed out by Leolo where loading gifs
skips the first line of the imageload() has been
by read() - for now load is an alias for read. It will
be removed in the future. Also, fixes dynamic loading on
systems that prepend an underscore to symbols. At the present
the only system that I know of that needs this is OpenBSD.
BUT YOU MUST RECOMPILE ALL OF YOUR OLD MODULES AGAINST THIS BUILD.
Added getchannels() method ( How did I manage to delay this
untill now ). Some document changes but nothing substantial.
Also fixed the png read/write routines to handle all colorspaces
and images with alpha information. Also now it's possible to
have Imager guess the format of the files to load or save
when passing files to read or save from the filename.
Also all of the tests except dynamic loading now pass on OS/2.
0.32 Tue Feb 29 17:26:00 2000 CPAN RELEASE
- Added the getcolorcount method. Fixed interlace handling
on png images. Fixed the missing channel count in crop()
method. Rewrote most of t1lib database stuff - created color
and font classes. T1 stuff is mostly done - TT things were
rewritten too and now include most of what is needed for
GIF/imgif.c view on Meta::CPAN
=item gif_background
The index in the global colormap of the logical screen's background
color. This is only set if the current image uses the global
colormap.
=item gif_trans_index
The index of the color in the colormap used for transparency. If the
image has a transparency then it is returned as a 4 channel image with
the alpha set to zero in this palette entry. ("Transparent Color Index")
=item gif_delay
The delay until the next frame is displayed, in 1/100 of a second.
("Delay Time").
=item gif_user_input
whether or not a user input is expected before continuing (view dependent)
("User Input Flag").
}
Imager->register_reader
(
type=>'ico',
single =>
sub {
my ($im, $io, %hsh) = @_;
my $masked =
exists $hsh{ico_masked} ? $hsh{ico_masked} : 1;
my $alpha_masked =
exists $hsh{ico_alpha_masked} ? $hsh{ico_alpha_masked} : 0;
$im->{IMG} = i_readico_single($io, $hsh{page} || 0, $masked,
$alpha_masked);
unless ($im->{IMG}) {
$im->_set_error(Imager->_error_as_msg);
return;
}
return $im;
},
multiple =>
sub {
my ($io, %hsh) = @_;
ICO/imicon.c view on Meta::CPAN
static void
ico_push_error(int error) {
char error_buf[ICO_MAX_MESSAGE];
ico_error_message(error, error_buf, sizeof(error_buf));
i_push_error(error, error_buf);
}
static
i_img *
read_one_icon(ico_reader_t *file, int index, int masked, int alpha_masked) {
ico_image_t *image;
int error;
i_img *result;
image = ico_image_read(file, index, &error);
if (!image) {
ico_push_error(error);
i_push_error(0, "error reading ICO/CUR image");
return NULL;
}
if (masked && (image->bit_count != 32 || alpha_masked)) {
/* check to make sure we should do the masking, if the mask has
nothing set we don't mask */
int pos;
int total = image->width * image->height;
unsigned char *inp = image->mask_data;
masked = 0;
for (pos = 0; pos < total; ++pos) {
if (*inp++) {
masked = 1;
ICO/t/t10icon.t view on Meta::CPAN
*****...........................
*****...........................
*****...........................
*****...........................';
is($im->tags(name => 'ico_mask'), $mask, "check ico_mask_tag");
# compare the pixels
# ppm can't store 4 channels
SKIP:
{
my $work = $im->convert(preset=>'noalpha');
my $comp = Imager->new;
$comp->read(file => "testimg/rgba3232.ppm")
or skip "could not read 24-bit comparison file:". $comp->errstr, 1;
is(Imager::i_img_diff($comp->{IMG}, $work->{IMG}), 0,
"compare image data");
}
ok($im->read(file => 'testimg/pal83232.ico', type=>'ico', ico_masked => 0),
"read 8 bit")
or print "# ", $im->errstr, "\n";
#define i_img_get_height(im) ((im)->ysize)
#define i_img_epsilonf() (DBL_EPSILON * 4)
/* avoid some xsubpp strangeness */
#define NEWLINE '\n'
#define ICL_red(c) ((c)->rgba.r)
#define ICL_green(c) ((c)->rgba.g)
#define ICL_blue(c) ((c)->rgba.b)
#define ICL_alpha(c) ((c)->rgba.a)
#define ICLF_red(c) ((c)->rgba.r)
#define ICLF_green(c) ((c)->rgba.g)
#define ICLF_blue(c) ((c)->rgba.b)
#define ICLF_alpha(c) ((c)->rgba.a)
MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
Imager::Color
ICL_new_internal(r,g,b,a)
unsigned char r
unsigned char g
unsigned char b
unsigned char a
T1/Makefile.PL
T1/README
T1/t/t10type1.t
T1/t/t20oo.t
T1/t/t30thread.t
T1/t/t90std.t Standard font tests for T1
T1/T1.pm
T1/T1.xs
T1/typemap
tags.c
testimg/alpha16.tga 16-bit/pixel TGA with alpha "channel" RT 32926
testimg/bad1oflow.bmp 1-bit/pixel, overflow integer on 32-bit machines
testimg/bad1wid0.bmp 1-bit/pixel, zero width
testimg/bad24comp.bmp 24-bit/pixel, bad compression
testimg/bad24oflow.bmp 24-bit/pixel, overflow integer on 32-bit machines
testimg/bad24wid0.bmp 24-bit/pixel, 0 width
testimg/bad4oflow.bmp 4-bit/pixel, overflow integer on 32-bit machines
testimg/bad4wid0.bmp 4-bit/pixel, 0 width
testimg/bad4widbig.bmp 4-bit/pixel, large width
testimg/bad8comp.bmp 8-bit/pixel, bad compression
testimg/bad8oflow.bmp 8-bit/pixel, overflow integer on 32-bit machines
PNG/t/10png.t view on Meta::CPAN
my $im = Imager->new;
ok($im->read(file => "testimg/gray.png", type => "png"),
"read grayscale");
is($im->getchannels, 1, "check channel count");
is($im->type, "direct", "check type");
is($im->bits, 8, "check bits");
is($im->tags(name => "png_bits"), 8, "check png_bits tag");
is($im->tags(name => "png_interlace"), 0, "check png_interlace tag");
}
{ # test grayscale + alpha read as greyscale + alpha
my $im = Imager->new;
ok($im->read(file => "testimg/graya.png", type => "png"),
"read grayscale + alpha");
is($im->getchannels, 2, "check channel count");
is($im->type, "direct", "check type");
is($im->bits, 8, "check bits");
is($im->tags(name => "png_bits"), 8, "check png_bits tag");
is($im->tags(name => "png_interlace"), 0, "check png_interlace tag");
}
{ # test paletted + alpha read as paletted
my $im = Imager->new;
ok($im->read(file => "testimg/paltrans.png", type => "png"),
"read paletted with alpha");
is($im->getchannels, 4, "check channel count");
is($im->type, "paletted", "check type");
is($im->tags(name => "png_bits"), 8, "check png_bits tag");
is($im->tags(name => "png_interlace"), 0, "check png_interlace tag");
}
{ # test paletted read as paletted
my $im = Imager->new;
ok($im->read(file => "testimg/pal.png", type => "png"),
"read paletted");
PNG/testimg/cover16.png matches view on Meta::CPAN
or diag("Cannot save testout/pal3.png: ".$pim->errstr);
my $in = Imager->new(file => "testout/pal3.png");
ok($in, "read it back in")
or diag("Cann't read pal3.png back: " . Imager->errstr);
is_image($pim, $in, "check it matches");
is($in->type, "paletted", "make sure the result is paletted");
is($in->tags(name => "png_bits"), 4, "4 bit representation");
}
{
# make sure the code that pushes maxed alpha to the end doesn't break
my $pim = Imager->new(xsize => 8, ysize => 2, channels => 4, type => "paletted");
ok($pim, "make a 4 channel paletted image");
ok($pim->addcolors
(colors => [ NC(255, 255, 0, 128), qw(000000 FFFFFF FF0000 00FF00 0000FF),
NC(0, 0, 0, 0), NC(255, 0, 128, 64) ]),
"add some colors");
is($pim->setscanline(y => 0, type => "index",
pixels => [ 5, 0, 1, 7, 2, 4, 6, 3 ]), 8,
"set some pixels");
is($pim->setscanline(y => 1, type => "index",
T1/t/t10type1.t view on Meta::CPAN
my $pound = pack("C*", 0xC2, 0xBF);
diff_text_with_nul("utf8 pound\0pound vs pound", "$pound\0$pound", $pound,
font => $font, color => '#FFFFFF', utf8 => 1);
diff_text_with_nul("utf8 dash\0dash vs dash", "$pound\0$pound", $pound,
font => $font, channel => 1, utf8 => 1);
}
{ # RT 11972
# when rendering to a transparent image the coverage should be
# expressed in terms of the alpha channel rather than the color
my $font = Imager::Font->new(file=>'fontfiles/dcr10.pfb', type=>'t1');
my $im = Imager->new(xsize => 40, ysize => 20, channels => 4);
ok($im->string(string => "AB", size => 20, aa => 2, color => '#F00',
x => 0, y => 15, font => $font),
"draw to transparent image");
my $im_noalpha = $im->convert(preset => 'noalpha');
my $im_pal = $im->to_paletted(make_colors => 'mediancut');
my @colors = $im_pal->getcolors;
is(@colors, 2, "should be only 2 colors");
@colors = sort { ($a->rgba)[0] <=> ($b->rgba)[0] } @colors;
is_color3($colors[0], 0, 0, 0, "check we got black");
is_color3($colors[1], 255, 0, 0, "and red");
}
SKIP:
{ # RT 60509
TIFF/imtiff.c view on Meta::CPAN
i_img_dim pixels_read;
int allow_incomplete;
void *line_buf;
tf_uint32 width, height;
tf_uint16 bits_per_sample;
tf_uint16 photometric;
/* the total number of channels (samples per pixel) */
int samples_per_pixel;
/* if non-zero, which channel is the alpha channel, typically 3 for rgb */
int alpha_chan;
/* whether or not to scale the color channels based on the alpha
channel. TIFF has 2 types of alpha channel, if the alpha channel
we use is EXTRASAMPLE_ASSOCALPHA then the color data will need to
be scaled to match Imager's conventions */
int scale_alpha;
/* number of color samples (not including alpha) */
int color_channels;
/* SampleFormat is 2 */
int sample_signed;
int sample_format;
};
static int tile_contig_getter(read_state_t *state, read_putter_t putter);
static int strip_contig_getter(read_state_t *state, read_putter_t putter);
TIFF/t/10tiff.t view on Meta::CPAN
"write multi to in memory");
ok(length $data, "make sure something written");
my @im = Imager->read_multi(data => $data);
is(@im, 2, "make sure we can read it back");
is(Imager::i_img_diff($im[0]{IMG}, $im->{IMG}), 0,
"check first image");
is(Imager::i_img_diff($im[1]{IMG}, $im->{IMG}), 0,
"check second image");
}
{ # handling of an alpha channel for various images
my $photo_rgb = 2;
my $photo_cmyk = 5;
my $photo_cielab = 8;
my @alpha_images =
(
[ 'srgb.tif', 3, $photo_rgb ],
[ 'srgba.tif', 4, $photo_rgb ],
[ 'srgbaa.tif', 4, $photo_rgb ],
[ 'scmyk.tif', 3, $photo_cmyk ],
[ 'scmyka.tif', 4, $photo_cmyk ],
[ 'scmykaa.tif', 4, $photo_cmyk ],
[ 'slab.tif', 3, $photo_cielab ],
);
for my $test (@alpha_images) {
my ($input, $channels, $photo) = @$test;
SKIP: {
my $skipped = $channels == 4 ? 4 : 3;
my $im = Imager->new;
ok($im->read(file => "testimg/$input"),
"read alpha test $input")
or print "# ", $im->errstr, "\n";
is($im->getchannels, $channels, "channels for $input match");
is($im->tags(name=>'tiff_photometric'), $photo,
"photometric for $input match");
$channels == 4
or next;
my $c = $im->getpixel(x => 0, 'y' => 7);
is(($c->rgba)[3], 0, "bottom row should have 0 alpha");
}
}
}
{
ok(grep($_ eq 'tiff', Imager->read_types), "check tiff in read types");
ok(grep($_ eq 'tiff', Imager->write_types), "check tiff in write types");
}
{ # reading tile based images
TIFF/testimg/alpha.tif matches view on Meta::CPAN
is($im->bits, 16, 'check image bits');
is($im->tags(name => 'tiff_photometric'), 2, "correct photometric");
is($im->tags(name => 'tiff_compression'), 'none', "no compression");
is($im->getchannels, 3, 'correct channels');
}
{ # 8-bit writes
# and check compression
my $compress = Imager::File::TIFF::i_tiff_has_compression('lzw') ? 'lzw' : 'packbits';
my $orig = test_image()->convert(preset=>'grey')
->convert(preset => 'addalpha');
my $data;
ok($orig->write(data => \$data, type => 'tiff',
tiff_compression=> $compress),
"write 8 bit")
or print "# ", $orig->errstr, "\n";
my $im = Imager->new;
ok($im->read(data => $data), "read it back");
is_image($im, $orig, "check read data matches");
is($im->tags(name => 'tiff_bitspersample'), 8, 'correct bits');
is($im->bits, 8, 'check image bits');
is($im->tags(name => 'tiff_photometric'), 1, 'correct photometric');
is($im->tags(name => 'tiff_compression'), $compress,
"$compress compression");
is($im->getchannels, 2, 'correct channels');
}
{ # double writes
my $orig = test_image_double()->convert(preset=>'addalpha');
my $data;
ok($orig->write(data => \$data, type => 'tiff',
tiff_compression => 'none'),
"write 32-bit/sample from double")
or diag $orig->errstr;
my $im = Imager->new;
ok($im->read(data => $data), "read it back");
is_image($im, $orig, "check read data matches");
is($im->tags(name => 'tiff_bitspersample'), 32, "correct bits");
is($im->bits, 'double', 'check image bits');
apidocs.perl view on Meta::CPAN
EOS
close OUT;
sub make_func_list {
my @funcs =
qw(i_img i_color i_fcolor i_fill_t mm_log mm_log i_color_model_t
im_context_t i_img_dim i_img_dim_u im_slot_t
i_polygon_t i_poly_fill_mode_t i_mutex_t
i_img_has_alpha i_DF i_DFc i_DFp i_DFcp i_psamp_bits i_gsamp_bits
i_psamp i_psampf);
open FUNCS, "< imexttypes.h"
or die "Cannot open imexttypes.h: $!\n";
my $in_struct;
while (<FUNCS>) {
/^typedef struct/ && ++$in_struct;
if ($in_struct && !/SKIP/ && /\(\*f_(i[om]?_\w+)/) {
my $name = $1;
$name =~ s/_imp$//;
push @funcs, $name;
#include "imageri.h"
#include "imrender.h"
#include <limits.h>
#define NDEBUG
#include <assert.h>
int
i_ppix_norm(i_img *im, i_img_dim x, i_img_dim y, i_color const *col) {
i_color src;
i_color work;
int dest_alpha;
int remains;
if (!col->channel[3])
return 0;
switch (im->channels) {
case 1:
work = *col;
i_adapt_colors(2, 4, &work, 1);
i_gpix(im, x, y, &src);
remains = 255 - work.channel[1];
src.channel[0] = (src.channel[0] * remains
+ work.channel[0] * work.channel[1]) / 255;
return i_ppix(im, x, y, &src);
case 2:
work = *col;
i_adapt_colors(2, 4, &work, 1);
i_gpix(im, x, y, &src);
remains = 255 - work.channel[1];
dest_alpha = work.channel[1] + remains * src.channel[1] / 255;
if (work.channel[1] == 255) {
return i_ppix(im, x, y, &work);
}
else {
src.channel[0] = (work.channel[1] * work.channel[0]
+ remains * src.channel[0] * src.channel[1] / 255) / dest_alpha;
src.channel[1] = dest_alpha;
return i_ppix(im, x, y, &src);
}
case 3:
work = *col;
i_gpix(im, x, y, &src);
remains = 255 - work.channel[3];
src.channel[0] = (src.channel[0] * remains
+ work.channel[0] * work.channel[3]) / 255;
src.channel[1] = (src.channel[1] * remains
+ work.channel[1] * work.channel[3]) / 255;
src.channel[2] = (src.channel[2] * remains
+ work.channel[2] * work.channel[3]) / 255;
return i_ppix(im, x, y, &src);
case 4:
work = *col;
i_gpix(im, x, y, &src);
remains = 255 - work.channel[3];
dest_alpha = work.channel[3] + remains * src.channel[3] / 255;
if (work.channel[3] == 255) {
return i_ppix(im, x, y, &work);
}
else {
src.channel[0] = (work.channel[3] * work.channel[0]
+ remains * src.channel[0] * src.channel[3] / 255) / dest_alpha;
src.channel[1] = (work.channel[3] * work.channel[1]
+ remains * src.channel[1] * src.channel[3] / 255) / dest_alpha;
src.channel[2] = (work.channel[3] * work.channel[2]
+ remains * src.channel[2] * src.channel[3] / 255) / dest_alpha;
src.channel[3] = dest_alpha;
return i_ppix(im, x, y, &src);
}
}
return 0;
}
static void
cfill_from_btm(i_img *im, i_fill_t *fill, struct i_bitmap *btm,
i_img_dim bxmin, i_img_dim bxmax, i_img_dim bymin, i_img_dim bymax);
i_fill_t *fill;
i_color c1, c2;
i_fcolor fc1, fc2;
int combine;
fill = i_new_fill_solidf(&fc1, combine);
fill = i_new_fill_solid(&c1, combine);
fill = i_new_fill_hatchf(&fc1, &fc2, combine, hatch, cust_hash, dx, dy);
fill = i_new_fill_hatch(&c1, &c2, combine, hatch, cust_hash, dx, dy);
fill = i_new_fill_image(im, matrix, xoff, yoff, combine);
fill = i_new_fill_opacity(fill, alpha_mult);
i_fill_destroy(fill);
=head1 DESCRIPTION
Implements the basic general fills, which can be used for filling some
shapes and for flood fills.
Each fill can implement up to 3 functions:
=over
/*
=head1 NAME
image.c - implements most of the basic functions of Imager and much of the rest
=head1 SYNOPSIS
i_img *i;
i_color *c;
c = i_color_new(red, green, blue, alpha);
ICL_DESTROY(c);
i = i_img_8_new();
i_img_destroy(i);
// and much more
=head1 DESCRIPTION
image.c implements the basic functions to create and destroy image and
color objects for Imager.
extern i_img *i_sametype_chans(i_img *im, i_img_dim xsize, i_img_dim ysize, int channels);
/* Image feature settings */
void i_img_setmask (i_img *im,int ch_mask);
int i_img_getmask (i_img *im);
int i_img_getchannels(i_img *im);
i_img_dim i_img_get_width(i_img *im);
i_img_dim i_img_get_height(i_img *im);
i_color_model_t i_img_color_model(i_img *im);
int i_img_alpha_channel(i_img *im, int *channel);
int i_img_color_channels(i_img *im);
/* Base functions */
extern int (i_ppix)(i_img *im,i_img_dim x,i_img_dim y, const i_color *val);
extern int (i_gpix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val);
extern int (i_ppixf)(i_img *im,i_img_dim x,i_img_dim y, const i_fcolor *val);
extern int (i_gpixf)(i_img *im,i_img_dim x,i_img_dim y,i_fcolor *val);
extern i_img_dim (i_plin)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y,
im_context_slot_new,
im_context_slot_set,
im_context_slot_get,
/* level 9 */
i_poly_poly_aa,
i_poly_poly_aa_cfill,
i_poly_aa_m,
i_poly_aa_cfill_m,
i_img_alpha_channel,
i_img_color_model,
i_img_color_channels,
/* level 10 */
im_decode_exif
/* level 11 */
};
/* in general these functions aren't called by Imager internally, but
#define i_mutex_destroy(m) ((im_extt->f_i_mutex_destroy)(m))
#define i_mutex_lock(m) ((im_extt->f_i_mutex_lock)(m))
#define i_mutex_unlock(m) ((im_extt->f_i_mutex_unlock)(m))
#define im_context_slot_new(destructor) ((im_extt->f_im_context_slot_new)(destructor))
#define im_context_slot_get(ctx, slot) ((im_extt->f_im_context_slot_get)((ctx), (slot)))
#define im_context_slot_set(ctx, slot, value) ((im_extt->f_im_context_slot_set)((ctx), (slot), (value)))
#define im_push_errorf (im_extt->f_im_push_errorf)
#define i_img_alpha_channel(im, channel) ((im_extt->f_i_img_alpha_channel)((im), (channel)))
#define i_img_color_model(im) ((im_extt->f_i_img_color_model)((im)))
#define i_img_color_channels(im) ((im_extt->f_i_img_color_channels)((im)))
#define im_decode_exif(im, data, len) ((im_extt->f_im_decode_exif)((im), (data), (len)))
#ifdef IMAGER_LOG
#ifndef IMAGER_NO_CONTEXT
#define mm_log(x) { i_lhead(__FILE__,__LINE__); i_loog x; }
#endif
#define im_log(x) { im_lhead(aIMCTX, __FILE__,__LINE__); im_loog x; }
view all matches for this distributionview release on metacpan - search on metacpan
( run in 7.345 seconds using v1.00-cache-2.02-grep-82fe00e-cpan-f5108d614456 )