$self->{ERRSTR} = "missing seed x and y parameters";
return undef;
}
-
+
if ($opts{fill}) {
unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
# assume it's a hash ref
much more cpu time but also gives considerable better results than the
median cut algorithm.
+When storing targa images rle compression can be activated with the
+'compress' parameter, the 'idstring' parameter can be used to set the
+targa comment field and the 'wierdpack' option can be used to use the
+15 and 16 bit targa formats for rgb and rgba data. The 15 bit format
+has 5 of each red, green and blue. The 16 bit format in addition
+allows 1 bit of alpha. The most significant bits are used for each
+channel.
+
Currently just for gif files, you can specify various options for the
conversion from Imager's internal RGB format to the target's indexed
file format. If you set the gifquant option to 'gen', you can use the
dyntest.c modified and recompiled.
load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
- $img->filter(%hsh);
+ $img->filter(%hsh);
-An example plugin comes with the module - Please send feedback to
+An example plugin comes with the module - Please send feedback to
addi@umich.edu if you test this.
Note: This seems to test ok on the following systems:
=head1 SEE ALSO
-perl(1), Imager::Color(3), Imager::Font(3), Imager::Matrix2d(3),
+perl(1), Imager::Color(3), Imager::Font(3), Imager::Matrix2d(3),
Affix::Infix2Postfix(3), Parse::RecDescent(3)
http://www.eecs.umich.edu/~addi/perl/Imager/
void
i_img_destroy(i_img *im) {
- mm_log((1,"i_img_destroy(im* 0x%x)\n",im));
+ mm_log((1,"i_img_destroy(im %p)\n",im));
i_img_exorcise(im);
if (im) { myfree(im); }
}
int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
int LanczosWidthFactor;
float *l0, *l1, OldLocation;
- int T, TempJump1, TempJump2;
+ int T;
+ float t;
float F, PictureValue[MAXCHANNELS];
short psave;
i_color val,val1,val2;
i_img *new_img;
- mm_log((1,"i_scaleaxis(im 0x%x,Value %.2f,Axis %d)\n",im,Value,Axis));
+ mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
if (Axis == XAXIS) {
- hsize = (int) ((float) im->xsize * Value);
+ hsize = (int)(0.5 + im->xsize * Value);
vsize = im->ysize;
jEnd = hsize;
iEnd = vsize;
-
- TempJump1 = (hsize - 1) * 3;
- TempJump2 = hsize * (vsize - 1) * 3 + TempJump1;
} else {
hsize = im->xsize;
- vsize = (int) ((float) im->ysize * Value);
-
+ vsize = (int)(0.5 + im->ysize * Value);
+
jEnd = vsize;
iEnd = hsize;
-
- TempJump1 = 0;
- TempJump2 = 0;
}
- new_img=i_img_empty_ch(NULL,hsize,vsize,im->channels);
-
- if (Value >=1) LanczosWidthFactor = 1;
- else LanczosWidthFactor = (int) (1.0/Value);
+ new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
+ /* 1.5 is a magic number, setting it to 2 will cause rather blurred images */
+ LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
lMax = LanczosWidthFactor << 1;
- l0 = (float *) mymalloc(lMax * sizeof(float));
- l1 = (float *) mymalloc(lMax * sizeof(float));
+ l0 = mymalloc(lMax * sizeof(float));
+ l1 = mymalloc(lMax * sizeof(float));
for (j=0; j<jEnd; j++) {
OldLocation = ((float) j) / Value;
T = (int) (OldLocation);
F = OldLocation - (float) T;
- for (l = 0; l < lMax; l++) {
+ for (l = 0; l<lMax; l++) {
l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
- l1[l] = Lanczos(((float) (l + 1) - F) / (float) LanczosWidthFactor);
+ l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
+ }
+
+ /* Make sure filter is normalized */
+ t = 0.0;
+ for(l=0; l<lMax; l++) {
+ t+=l0[l];
+ t+=l1[l];
}
+ t /= (float)LanczosWidthFactor;
- if (Axis== XAXIS) {
+ for(l=0; l<lMax; l++) {
+ l0[l] /= t;
+ l1[l] /= t;
+ }
+
+ if (Axis == XAXIS) {
for (i=0; i<iEnd; i++) {
for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
for (l=0; l < lMax; l++) {
- i_gpix(im,T+l+1, i, &val1);
- i_gpix(im,T-lMax+l+1, i, &val2);
+ i_gpix(im, T+l+1, i, &val1);
+ i_gpix(im, T-lMax+l+1, i, &val2);
for (k=0; k<im->channels; k++) {
- PictureValue[k] += l1[l] * val1.channel[k];
+ PictureValue[k] += l1[l] * val1.channel[k];
PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
}
}
for(k=0;k<im->channels;k++) {
- psave = (short)( PictureValue[k] / LanczosWidthFactor);
+ psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
val.channel[k]=minmax(0,255,psave);
}
- i_ppix(new_img,j,i,&val);
+ i_ppix(new_img, j, i, &val);
}
} else {
for (i=0; i<iEnd; i++) {
for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
for (l=0; l < lMax; l++) {
- i_gpix(im,i, T+l+1, &val1);
- i_gpix(im,i, T-lMax+l+1, &val2);
+ i_gpix(im, i, T+l+1, &val1);
+ i_gpix(im, i, T-lMax+l+1, &val2);
for (k=0; k<im->channels; k++) {
PictureValue[k] += l1[l] * val1.channel[k];
PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
}
for (k=0; k<im->channels; k++) {
psave = (short)( PictureValue[k] / LanczosWidthFactor);
- val.channel[k]=minmax(0,255,psave);
+ val.channel[k] = minmax(0, 255, psave);
}
- i_ppix(new_img,i,j,&val);
+ i_ppix(new_img, i, j, &val);
}
}
myfree(l0);
myfree(l1);
- mm_log((1,"(0x%x) <- i_scaleaxis\n",new_img));
+ mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
return new_img;
}
}
if (cp >= pixels) break;
tlen = find_span(buf+cp*s->bytepp, pixels-cp, s->bytepp);
+ if (tlen <3) continue;
while (tlen) {
int clen = (tlen>128) ? 128 : tlen;
clen = (clen - 1) | 0x80;
i_img *
i_readtga_wiol(io_glue *ig, int length) {
- i_img* img;
+ i_img* img = NULL;
int x, y, i;
int width, height, channels;
int mapped;
- char *idstring;
+ char *idstring = NULL;
tga_source src;
tga_header header;
i_push_error(errno, "short read on targa idstring");
return NULL;
}
- myfree(idstring); /* Move this later, once this is stored in a tag */
}
width = header.width;
switch (header.datatypecode) {
case 0: /* No data in image */
i_push_error(0, "Targa image contains no image data");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 1: /* Uncompressed, color-mapped images */
case 11: /* Compressed, grayscale images */
if (header.bitsperpixel != 8) {
i_push_error(0, "Targa: mapped/grayscale image's bpp is not 8, unsupported.");
+ if (idstring) myfree(idstring);
return NULL;
}
src.bytepp = 1;
if ((src.bytepp = bpp_to_bytes(header.bitsperpixel)))
break;
i_push_error(0, "Targa: direct color image's bpp is not 15/16/24/32 - unsupported.");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 32: /* Compressed color-mapped, Huffman, Delta and runlength */
case 33: /* Compressed color-mapped, Huffman, Delta and runlength */
i_push_error(0, "Unsupported Targa (Huffman/delta/rle/quadtree) subformat is not supported");
+ if (idstring) myfree(idstring);
return NULL;
break;
default: /* All others which we don't know which might be */
i_push_error(0, "Unknown targa format");
+ if (idstring) myfree(idstring);
return NULL;
break;
}
header.colourmapdepth :
header.bitsperpixel))) break;
i_push_error(0, "Targa Image has none of 15/16/24/32 pixel layout");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 3: /* Uncompressed, grayscale images */
i_img_pal_new(width, height, channels, 256) :
i_img_empty_ch(NULL, width, height, channels);
+ if (idstring) {
+ i_tags_add(&img->tags, "tga_idstring", 0, idstring, header.idlength, 0);
+ free(idstring);
+ }
+
if (mapped &&
!tga_palette_read(ig,
img,
header.colourmaplength)
) {
i_push_error(0, "Targa Image has none of 15/16/24/32 pixel layout");
+ if (idstring) myfree(idstring);
+ if (img) i_img_destroy(img);
return NULL;
}
if (!tga_source_read(&src, databuf, width)) {
i_push_error(errno, "read for targa data failed");
myfree(databuf);
+ if (img) i_img_destroy(img);
return NULL;
}
if (mapped && header.colourmaporigin) for(x=0; x<width; x++) databuf[x] -= header.colourmaporigin;
}
myfree(databuf);
if (linebuf) myfree(linebuf);
+
+ i_tags_addn(&img->tags, "tga_bitspp", 0, mapped?header.colourmapdepth:header.bitsperpixel);
+ if (src.compressed) i_tags_addn(&img->tags, "compressed", 0, 1);
return img;
}