use vars qw($VERSION @ISA);
BEGIN {
- $VERSION = "0.03";
+ $VERSION = "0.04";
require XSLoader;
XSLoader::load('Imager::File::ICO', $VERSION);
my ($im, $io, %hsh) = @_;
my $masked =
exists $hsh{ico_masked} ? $hsh{ico_masked} : 1;
- $im->{IMG} = i_readico_single($io, $hsh{page} || 0, $masked);
+ 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);
my ($im, $io, %hsh) = @_;
my $masked =
exists $hsh{ico_masked} ? $hsh{ico_masked} : 1;
- $im->{IMG} = i_readico_single($io, $hsh{page} || 0, $masked);
+ 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);
PROTOTYPES: DISABLE
Imager::ImgRaw
-i_readico_single(ig, index, masked = 0)
+i_readico_single(ig, index, masked = 0, alpha_masked = 0)
Imager::IO ig
int index
bool masked
+ bool alpha_masked
void
-i_readico_multi(ig, masked = 0)
+i_readico_multi(ig, masked = 0, alpha_masked = 0)
Imager::IO ig
bool masked
+ bool alpha_masked
PREINIT:
i_img **imgs;
int count;
int i;
PPCODE:
- imgs = i_readico_multi(ig, &count, masked);
+ imgs = i_readico_multi(ig, &count, masked, alpha_masked);
if (imgs) {
EXTEND(SP, count);
for (i = 0; i < count; ++i) {
static
i_img *
-read_one_icon(ico_reader_t *file, int index, int masked) {
+read_one_icon(ico_reader_t *file, int index, int masked, int alpha_masked) {
ico_image_t *image;
int error;
i_img *result;
return NULL;
}
- if (masked) {
+ 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;
}
i_img *
-i_readico_single(io_glue *ig, int index, int masked) {
+i_readico_single(io_glue *ig, int index, int masked, int alpha_masked) {
ico_reader_t *file;
i_img *result;
int error;
/* the index is range checked by msicon.c - don't duplicate it here */
- result = read_one_icon(file, index, masked);
+ result = read_one_icon(file, index, masked, alpha_masked);
ico_reader_close(file);
return result;
}
i_img **
-i_readico_multi(io_glue *ig, int *count, int masked) {
+i_readico_multi(io_glue *ig, int *count, int masked, int alpha_masked) {
ico_reader_t *file;
int index;
int error;
*count = 0;
for (index = 0; index < ico_image_count(file); ++index) {
- i_img *im = read_one_icon(file, index, masked);
+ i_img *im = read_one_icon(file, index, masked, alpha_masked);
if (!im)
break;
#include "imext.h"
extern i_img *
-i_readico_single(io_glue *ig, int index, int masked);
+i_readico_single(io_glue *ig, int index, int masked, int alpha_masked);
extern i_img **
-i_readico_multi(io_glue *ig, int *count, int masked);
+i_readico_multi(io_glue *ig, int *count, int masked, int alpha_masked);
extern int
i_writeico_wiol(i_io_glue_t *ig, i_img *im);
#!perl -w
use strict;
-use Test::More tests => 106;
-use Imager::Test qw(is_image test_image);
+use Test::More tests => 111;
+use Imager::Test qw(is_image isnt_image test_image);
BEGIN { use_ok('Imager::File::ICO'); }
}
}
+{ # RT #99507
+ # we now ignore the mask by default when reading a 32-bit image
+ my $im = Imager->new(xsize => 2, ysize => 2, channels => 4);
+ $im->setpixel(x => 0, y => 0, color => "#FF0000");
+ $im->setpixel(x => 1, y => 1, color => "#00FF00");
+ my $mask = <<EOS;
+01
+00
+11
+EOS
+ my $data;
+ ok($im->write(data => \$data,
+ type => "ico",
+ ico_mask => $mask), "write with dodgy mask");
+ my $im2 = Imager->new(data => \$data, filetype => "ico");
+ ok($im2, "read it back");
+ is_image($im2, $im, "should match original, despite bad mask");
+ my $im3 = Imager->new(data => \$data, filetype => "ico", ico_alpha_masked => 1);
+ ok($im3, "read it back with ico_alpha_masked => 1");
+ my $cmp = $im->copy;
+ $cmp->setpixel(x => 0, y => 0, color => [ 255, 0, 0, 0 ]);
+ isnt_image($im3, $cmp, "bad mask makes some pixels transparent");
+}
=item *
-ico_masked - if true, the default, then the icon/cursors mask is
-applied as an alpha channel to the image. This may result in a
-paletted image being returned as a direct color image. Default: 1
+C<ico_masked> - if true, the default, then the icon/cursors mask is
+applied as an alpha channel to the image, unless that image already
+has an alpha channel. This may result in a paletted image being
+returned as a direct color image. Default: 1
# retrieve the image as stored, without using the mask as an alpha
# channel
This was introduced in Imager 0.60. Previously reading ICO images
acted as if C<ico_masked =E<gt> 0>.
+=item *
+
+C<ico_alpha_masked> - if true, then the icon/cursor mask is applied as
+an alpha channel to images that already have an alpha mask. Note that
+this will only make pixels transparent, not opaque. Default: 0.
+
+Note: If you get different results between C<ico_alpha_masked> being
+set to 0 and 1, your mask may broke when used with the Win32 API.
+
=back
C<cur_bits> is set when reading a cursor.