Skip to content
Browse files

switch to using size_t and i_img_dim strictly

Also, use double instead of float where the value is used in
calculating a co-ordinate, since float may not be able to represent an
image ordinate with sufficient precision
  • Loading branch information...
1 parent bd80e51 commit 8d14daabc32a4346d5c20dbe864acc65ca66315b @tonycoz committed Jun 14, 2011
Showing with 4,900 additions and 1,774 deletions.
  1. +34 −0 Changes
  2. +2 −1 CountColor/CountColor.xs
  3. +2 −5 DynTest/linstretch.c
  4. +15 −14 FT2/FT2.xs
  5. +27 −24 FT2/freetyp2.c
  6. +12 −7 FT2/imft2.h
  7. +3 −3 Flines/Flines.xs
  8. +25 −14 GIF/imgif.c
  9. +88 −0 GIF/t/t40limit.t
  10. +259 −332 Imager.xs
  11. +1 −0 JPEG/imexif.c
  12. +12 −3 JPEG/imjpeg.c
  13. +54 −0 JPEG/t/t20limit.t
  14. +5 −0 MANIFEST
  15. +22 −0 Makefile.PL
  16. +2 −1 Mandelbrot/mandel.c
  17. +8 −1 PNG/impng.c
  18. +8 −0 SGI/imsgi.c
  19. +52 −0 SGI/t/30limit.t
  20. +8 −8 T1/T1.xs
  21. +14 −13 T1/imt1.c
  22. +3 −3 T1/imt1.h
  23. +63 −53 TIFF/imtiff.c
  24. +2 −0 W32/W32.pm
  25. +11 −11 W32/W32.xs
  26. +5 −5 W32/imw32.h
  27. +28 −18 W32/win32.c
  28. +5 −1 apidocs.perl
  29. +68 −30 bmp.c
  30. +25 −22 compose.im
  31. +4 −4 conv.im
  32. +3 −2 convert.im
  33. +103 −46 datatypes.c
  34. +139 −133 draw.c
  35. +9 −8 draw.h
  36. +8 −6 dynaload.c
  37. +4 −4 dynfilt/dt2.c
  38. +7 −5 dynfilt/dyntest.c
  39. +5 −5 dynfilt/flines.c
  40. +9 −9 dynfilt/mandelbrot.c
  41. +7 −3 error.c
  42. +5 −0 fileformatdocs/other.txt
  43. +2,476 −0 fileformatdocs/spec-gif89a.txt
  44. BIN fileformatdocs/tga_specs.pdf
  45. BIN fileformatdocs/tgaffs.pdf
  46. +20 −19 fills.c
  47. +140 −173 filters.im
  48. +5 −5 flip.im
  49. +81 −79 font.c
  50. +11 −10 gaussian.im
  51. +16 −16 hlines.c
  52. +101 −81 image.c
  53. +92 −114 imager.h
  54. +17 −16 imageri.h
  55. +89 −43 imdatatypes.h
  56. +1 −1 imerror.h
  57. +20 −20 imext.c
  58. +7 −0 imext.h
  59. +51 −46 imexttypes.h
  60. +64 −51 img16.c
  61. +51 −41 img8.c
  62. +53 −42 imgdouble.c
  63. +28 −22 io.c
  64. +13 −13 iolayer.c
  65. +1 −0 iolayert.h
  66. +167 −3 lib/Imager/APIRef.pod
  67. +1 −1 lib/Imager/Cookbook.pod
  68. +5 −5 lib/Imager/Files.pod
  69. +45 −18 limits.c
  70. +1 −0 log.c
  71. +2 −1 log.h
  72. +1 −1 map.c
  73. +46 −46 maskimg.c
  74. +30 −30 palimg.c
  75. +14 −11 paste.im
  76. +22 −17 pnm.c
  77. +12 −17 polygon.c
  78. +19 −16 quant.c
  79. +19 −15 raw.c
  80. +6 −6 regmach.c
  81. +7 −1 render.im
Sorry, we could not display the entire diff because it was too big.
View
34 Changes
@@ -1,5 +1,39 @@
Imager release history. Older releases can be found in Changes.old
+Imager 0.85
+===========
+
+Massive types re-work:
+
+ - the type used internally for pixel co-ordinates and image sizes is
+ now 64-bit on 64-bit platforms (at least sane ones).
+
+ - size_t is now used consistently for memory block sizes.
+
+ - since this changes the binary interface, the Imager API version has
+ been incremented. Any module that uses the API will need to be
+ rebuilt. In most cases that will be enough, but calls to any APIs
+ that take a pointer to image sizes may need source changes.
+
+ - you should be able to create very large images on 64-bit systems,
+ if you have enough memory. Successfully created a 32768 x 49192 x
+ 3 channel image, filled with a tiled image and scaled it. The
+ unscaled image was also successfully saved to a JPEG.
+
+ - check the image size before attempting to write BMP, GIF, JPEG,
+ PNG, SGI, TGA, TIFF images.
+
+ - correctly handle reading TGA images over 32767 pixels wide or tall.
+
+Incidental changes:
+
+ - the gif_left and gif_top tags are now clamped to non-negative
+ values when writing a GIF image.
+
+ - removed dead callback read/write code
+
+The default maximum memory size when reading files is now 1G.
+
Imager 0.84 - 20 Jun 2011
===========
View
3 CountColor/CountColor.xs
@@ -17,7 +17,8 @@ DEFINE_IMAGER_CALLBACKS;
int
count_color(i_img *im, i_color *color) {
- int x, y, chan;
+ i_img_dim x, y;
+ int chan;
i_color c;
int count = 0;
View
7 DynTest/linstretch.c
@@ -29,14 +29,11 @@ saturate(int in) {
void lin_stretch(i_img *im, int a, int b) {
i_color rcolor;
- int i,bytes,x,y;
- int info[4];
+ i_img_dim x,y;
+ int i;
/* fprintf(stderr,"parameters: (im 0x%x,a %d,b %d)\n",im,a,b);*/
- bytes=im->bytes;
-
- i_img_info(im,info);
for(y=0;y<im->ysize;y++) for(x=0;x<im->xsize;x++) {
i_gpix(im,x,y,&rcolor);
View
29 FT2/FT2.xs
@@ -22,6 +22,7 @@ FT2_DESTROY(font)
int
FT2_CLONE_SKIP(...)
CODE:
+ (void)items;
RETVAL = 1;
OUTPUT:
RETVAL
@@ -90,7 +91,7 @@ i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
SV *text_sv
int utf8
PREINIT:
- int bbox[BOUNDING_BOX_COUNT];
+ i_img_dim bbox[BOUNDING_BOX_COUNT];
int i;
char *text;
STRLEN text_len;
@@ -117,7 +118,7 @@ i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
int vlayout
int utf8
PREINIT:
- int bbox[8];
+ i_img_dim bbox[8];
int i;
PPCODE:
#ifdef SvUTF8
@@ -135,8 +136,8 @@ undef_int
i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
Imager::Font::FT2x font
Imager::ImgRaw im
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
Imager::Color cl
double cheight
double cwidth
@@ -163,8 +164,8 @@ undef_int
i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
Imager::Font::FT2x font
Imager::ImgRaw im
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
int channel
double cheight
double cwidth
@@ -190,12 +191,12 @@ i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout
void
ft2_transform_box(font, x0, x1, x2, x3)
Imager::Font::FT2x font
- int x0
- int x1
- int x2
- int x3
+ i_img_dim x0
+ i_img_dim x1
+ i_img_dim x2
+ i_img_dim x3
PREINIT:
- int box[4];
+ i_img_dim box[4];
PPCODE:
box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
ft2_transform_box(font, box);
@@ -214,8 +215,8 @@ i_ft2_has_chars(handle, text_sv, utf8)
char *text;
STRLEN len;
char *work;
- int count;
- int i;
+ size_t count;
+ size_t i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
@@ -241,7 +242,7 @@ i_ft2_face_name(handle)
Imager::Font::FT2x handle
PREINIT:
char name[255];
- int len;
+ size_t len;
PPCODE:
len = i_ft2_face_name(handle, name, sizeof(name));
if (len) {
View
51 FT2/freetyp2.c
@@ -12,7 +12,7 @@ freetyp2.c - font support via the FreeType library version 2.
if (!i_ft2_getdpi(font, &xdpi, &ydpi)) { error }
double matrix[6];
if (!i_ft2_settransform(font, matrix)) { error }
- int bbox[BOUNDING_BOX_COUNT];
+ i_img_dim bbox[BOUNDING_BOX_COUNT];
if (!i_ft2_bbox(font, cheight, cwidth, text, length, bbox, utf8)) { error }
i_img *im = ...;
i_color cl;
@@ -52,8 +52,8 @@ static void ft2_push_message(int code);
static int ft2_initialized = 0;
static FT_Library library;
-static int i_min(int a, int b);
-static int i_max(int a, int b);
+static i_img_dim i_min(i_img_dim a, i_img_dim b);
+static i_img_dim i_max(i_img_dim a, i_img_dim b);
/*
=item i_ft2_init(void)
@@ -318,7 +318,7 @@ int i_ft2_sethinting(FT2_Fonthandle *handle, int hinting) {
}
/*
-=item i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth, char *text, size_t len, int *bbox)
+=item i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth, char *text, size_t len, i_img_dim *bbox)
Retrieves bounding box information for the font at the given
character width and height. This ignores the transformation matrix.
@@ -329,9 +329,9 @@ Returns non-zero on success.
*/
int
i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, size_t len, int *bbox, int utf8) {
+ char const *text, size_t len, i_img_dim *bbox, int utf8) {
FT_Error error;
- int width;
+ i_img_dim width;
int index;
int first;
int ascent = 0, descent = 0;
@@ -439,7 +439,7 @@ too much hard work.
=cut
*/
-void ft2_transform_box(FT2_Fonthandle *handle, int bbox[4]) {
+void ft2_transform_box(FT2_Fonthandle *handle, i_img_dim bbox[4]) {
double work[8];
double *matrix = handle->matrix;
@@ -466,15 +466,15 @@ bounding box in bbox[] that encloses both.
=cut
*/
-static void expand_bounds(int bbox[4], int bbox2[4]) {
+static void expand_bounds(i_img_dim bbox[4], i_img_dim bbox2[4]) {
bbox[0] = i_min(bbox[0], bbox2[0]);
bbox[1] = i_min(bbox[1], bbox2[1]);
bbox[2] = i_max(bbox[2], bbox2[2]);
bbox[3] = i_max(bbox[3], bbox2[3]);
}
/*
-=item i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth, char *text, size_t len, int vlayout, int utf8, int *bbox)
+=item i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth, char *text, size_t len, int vlayout, int utf8, i_img_dim *bbox)
Retrieves bounding box information for the font at the given
character width and height.
@@ -495,16 +495,16 @@ Returns non-zero on success.
*/
int
i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, size_t len, int vlayout, int utf8, int *bbox) {
+ char const *text, size_t len, int vlayout, int utf8, i_img_dim *bbox) {
FT_Error error;
- int width;
+ i_img_dim width;
int index;
int first;
- int ascent = 0, descent = 0;
+ i_img_dim ascent = 0, descent = 0;
int glyph_ascent, glyph_descent;
FT_Glyph_Metrics *gm;
- int work[4];
- int bounds[4];
+ i_img_dim work[4];
+ i_img_dim bounds[4];
double x = 0, y = 0;
int i;
FT_GlyphSlot slot;
@@ -641,13 +641,13 @@ Returns non-zero on success.
=cut
*/
int
-i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty, const i_color *cl,
+i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const i_color *cl,
double cheight, double cwidth, char const *text, size_t len,
int align, int aa, int vlayout, int utf8) {
FT_Error error;
int index;
FT_Glyph_Metrics *gm;
- int bbox[BOUNDING_BOX_COUNT];
+ i_img_dim bbox[BOUNDING_BOX_COUNT];
FT_GlyphSlot slot;
int x, y;
unsigned char *bmp;
@@ -790,10 +790,10 @@ Returns non-zero on success.
*/
int
-i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty, int channel,
+i_ft2_cp(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, int channel,
double cheight, double cwidth, char const *text, size_t len, int align,
int aa, int vlayout, int utf8) {
- int bbox[8];
+ i_img_dim bbox[8];
i_img *work;
i_color cl, cl2;
int x, y;
@@ -843,7 +843,8 @@ Returns the number of characters that were checked.
=cut
*/
-int i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, size_t len,
+size_t
+i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, size_t len,
int utf8, char *out) {
int count = 0;
mm_log((1, "i_ft2_has_chars(handle %p, text %p, len %d, utf8 %d)\n",
@@ -953,10 +954,12 @@ make_bmp_map(FT_Bitmap *bitmap, unsigned char *map) {
Fills the given buffer with the Postscript Face name of the font,
if there is one.
+Returns the number of bytes copied, including the terminating NUL.
+
=cut
*/
-int
+size_t
i_ft2_face_name(FT2_Fonthandle *handle, char *name_buf, size_t name_buf_size) {
#if IM_HAS_FACE_NAME
char const *name = FT_Get_Postscript_Name(handle->face);
@@ -1134,13 +1137,13 @@ i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, const long *coords)
#endif
}
-static int
-i_min(int a, int b) {
+static i_img_dim
+i_min(i_img_dim a, i_img_dim b) {
return a < b ? a : b;
}
-static int
-i_max(int a, int b) {
+static i_img_dim
+i_max(i_img_dim a, i_img_dim b) {
return a > b ? a : b;
}
View
19 FT2/imft2.h
@@ -15,21 +15,23 @@ extern int i_ft2_getdpi(FT2_Fonthandle *handle, int *xdpi, int *ydpi);
extern int i_ft2_settransform(FT2_Fonthandle *handle, const double *matrix);
extern int i_ft2_sethinting(FT2_Fonthandle *handle, int hinting);
extern int i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, size_t len, int *bbox, int utf8);
+ char const *text, size_t len, i_img_dim *bbox, int utf8);
extern int i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, size_t len, int vlayout, int utf8, int *bbox);
-extern int i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
+ char const *text, size_t len, int vlayout, int utf8, i_img_dim *bbox);
+extern int i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty,
const i_color *cl, double cheight, double cwidth,
char const *text, size_t len, int align, int aa,
int vlayout, int utf8);
-extern int i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
+extern int i_ft2_cp(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty,
int channel, double cheight, double cwidth,
char const *text, size_t len, int align, int aa,
int vlayout, int utf8);
-extern int i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, size_t len,
+extern size_t
+i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, size_t len,
int utf8, char *work);
-extern int i_ft2_face_name(FT2_Fonthandle *handle, char *name_buf,
- size_t name_buf_size);
+extern size_t
+i_ft2_face_name(FT2_Fonthandle *handle, char *name_buf,
+ size_t name_buf_size);
extern int i_ft2_can_face_name(void);
extern int i_ft2_glyph_name(FT2_Fonthandle *handle, unsigned long ch,
char *name_buf, size_t name_buf_size,
@@ -43,5 +45,8 @@ extern int
i_ft2_is_multiple_master(FT2_Fonthandle *handle);
extern int
i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, const long *coords);
+
+void ft2_transform_box(FT2_Fonthandle *handle, i_img_dim bbox[4]);
+
#endif
View
6 Flines/Flines.xs
@@ -26,19 +26,19 @@ saturate(int in) {
void
flines(i_img *im) {
i_color vl;
- int x,y;
+ i_img_dim x,y;
for(y = 0; y < im->ysize; y ++) {
for(x = 0; x < im->xsize; x ++ ) {
i_gpix(im,x,y,&vl);
if (!(y%2)) {
- float yf = y/(float)im->ysize;
+ float yf = y/(double)im->ysize;
float mf = 1.2-0.8*yf;
vl.rgb.r = saturate(vl.rgb.r*mf);
vl.rgb.g = saturate(vl.rgb.g*mf);
vl.rgb.b = saturate(vl.rgb.b*mf);
} else {
- float yf = (im->ysize-y)/(float)im->ysize;
+ float yf = (im->ysize-y)/(double)im->ysize;
float mf = 1.2-0.8*yf;
vl.rgb.r = saturate(vl.rgb.r*mf);
vl.rgb.g = saturate(vl.rgb.g*mf);
View
39 GIF/imgif.c
@@ -8,6 +8,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
/*
=head1 NAME
@@ -61,8 +62,6 @@ functionality with giflib3.
static char const *gif_error_msg(int code);
static void gif_push_error(void);
-static int gif_read_callback(GifFileType *gft, GifByteType *buf, int length);
-
/* Make some variables global, so we could access them faster: */
static int
@@ -1244,7 +1243,6 @@ quantizing to the caller specified palette.
static int
has_common_palette(i_img **imgs, int count, i_quantize *quant) {
- int size = quant->mc_count;
int i;
int imgn;
char used[256];
@@ -1306,7 +1304,7 @@ quant_paletted(i_quantize *quant, i_img *img) {
i_palidx *p = data;
i_palidx trans[256];
int i;
- int x, y;
+ i_img_dim x, y;
/* build a translation table */
for (i = 0; i < i_colorcount(img); ++i) {
@@ -1379,34 +1377,47 @@ i_writegif_low(i_quantize *quant, GifFileType *gf, i_img **imgs, int count) {
if (!i_tags_get_int(&imgs[0]->tags, "gif_screen_width", 0, &scrw))
scrw = 0;
if (!i_tags_get_int(&imgs[0]->tags, "gif_screen_height", 0, &scrh))
- scrw = 0;
+ scrh = 0;
anylocal = 0;
localmaps = mymalloc(sizeof(int) * count);
glob_imgs = mymalloc(sizeof(i_img *) * count);
glob_img_count = 0;
glob_want_trans = 0;
for (imgn = 0; imgn < count; ++imgn) {
+ i_img *im = imgs[imgn];
+ if (im->xsize > 0xFFFF || im->ysize > 0xFFFF) {
+ i_push_error(0, "image too large for GIF");
+ return 0;
+ }
+
posx = posy = 0;
- i_tags_get_int(&imgs[imgn]->tags, "gif_left", 0, &posx);
- i_tags_get_int(&imgs[imgn]->tags, "gif_top", 0, &posy);
- if (imgs[imgn]->xsize + posx > scrw)
- scrw = imgs[imgn]->xsize + posx;
- if (imgs[imgn]->ysize + posy > scrh)
- scrh = imgs[imgn]->ysize + posy;
- if (!i_tags_get_int(&imgs[imgn]->tags, "gif_local_map", 0, localmaps+imgn))
+ i_tags_get_int(&im->tags, "gif_left", 0, &posx);
+ if (posx < 0) posx = 0;
+ i_tags_get_int(&im->tags, "gif_top", 0, &posy);
+ if (posy < 0) posy = 0;
+ if (im->xsize + posx > scrw)
+ scrw = im->xsize + posx;
+ if (im->ysize + posy > scrh)
+ scrh = im->ysize + posy;
+ if (!i_tags_get_int(&im->tags, "gif_local_map", 0, localmaps+imgn))
localmaps[imgn] = 0;
if (localmaps[imgn])
anylocal = 1;
else {
- if (imgs[imgn]->channels == 4) {
+ if (im->channels == 4) {
glob_want_trans = 1;
}
- glob_imgs[glob_img_count++] = imgs[imgn];
+ glob_imgs[glob_img_count++] = im;
}
}
glob_want_trans = glob_want_trans && quant->transp != tr_none ;
+ if (scrw > 0xFFFF || scrh > 0xFFFF) {
+ i_push_error(0, "screen size too large for GIF");
+ return 0;
+ }
+
orig_count = quant->mc_count;
orig_size = quant->mc_size;
View
88 GIF/t/t40limit.t
@@ -0,0 +1,88 @@
+#!perl -w
+use Imager;
+use Test::More tests => 22;
+use Imager::Test qw(is_image);
+
+{
+ # GIF files are limited to 0xFFFF x 0xFFFF pixels
+ {
+ my $im = Imager->new(xsize => 0x10000, ysize => 1);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "fail to write too wide an image");
+ is($im->errstr, "image too large for GIF",
+ "check error message");
+ }
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 0xFFFF, ysize => 1);
+ $im->box(fill => { hatch => "check4x4" });
+ my $data = '';
+ ok($im->write(data => \$data, type => "gif"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "gif");
+ ok($im2, "read it ok")
+ or skip("cannot load the wide image", 1);
+ is_image($im, $im2, "check we read what we wrote");
+ is($im->getwidth, 0xffff, "check width");
+ is($im->getheight, 1, "check height");
+ }
+ {
+ my $im = Imager->new(xsize => 1, ysize => 0x10000);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "fail to write too tall an image");
+ is($im->errstr, "image too large for GIF",
+ "check error message");
+ }
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 1, ysize => 0xFFFF);
+ $im->box(fill => { hatch => "check2x2" });
+ my $data = '';
+ ok($im->write(data => \$data, type => "gif"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "gif");
+ ok($im2, "read it ok")
+ or skip("cannot load the wide image", 1);
+ is_image($im, $im2, "check we read what we wrote");
+ is($im->getwidth, 1, "check width");
+ is($im->getheight, 0xffff, "check height");
+ }
+}
+{
+ my $im = Imager->new(xsize => 1, ysize => 1);
+ $im->settag(name => "gif_screen_width", value => 65536);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "save a with a large explicit screen width should fail");
+ is($im->errstr, "screen size too large for GIF",
+ "check error message");
+}
+{
+ my $im = Imager->new(xsize => 0x8000, ysize => 1);
+ $im->settag(name => "gif_left", value => 32768);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "save a with a large implicit screen width should fail");
+ is($im->errstr, "screen size too large for GIF",
+ "check error message");
+}
+{
+ my $im = Imager->new(xsize => 1, ysize => 1);
+ $im->settag(name => "gif_screen_height", value => 65536);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "save a with a large explicit screen height should fail");
+ is($im->errstr, "screen size too large for GIF",
+ "check error message");
+}
+{
+ my $im = Imager->new(xsize => 1, ysize => 0x8000);
+ $im->settag(name => "gif_top", value => 32768);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "gif"),
+ "save a with a large implicit screen height should fail");
+ is($im->errstr, "screen size too large for GIF",
+ "check error message");
+}
View
591 Imager.xs
@@ -34,7 +34,7 @@ static int getstr(void *hv_t,char *key,char **store) {
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
@@ -49,7 +49,7 @@ static int getint(void *hv_t,char *key,int *store) {
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
@@ -63,11 +63,11 @@ static int getdouble(void *hv_t,char* key,double *store) {
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
svpp=hv_fetch(hv, key, strlen(key), 0);
- *store=(float)SvNV(*svpp);
+ *store=(double)SvNV(*svpp);
return 1;
}
@@ -76,7 +76,7 @@ static int getvoid(void *hv_t,char* key,void **store) {
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
+ mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
@@ -91,7 +91,7 @@ static int getobj(void *hv_t,char *key,char *type,void **store) {
SV** svpp;
HV* hv=(HV*)hv_t;
- mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
+ mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
if ( !hv_exists(hv,key,strlen(key)) ) return 0;
@@ -122,98 +122,6 @@ i_log_entry(char *string, int level) {
}
-typedef struct i_reader_data_tag
-{
- /* presumably a CODE ref or name of a sub */
- SV *sv;
-} i_reader_data;
-
-/* used by functions that want callbacks */
-static int read_callback(char *userdata, char *buffer, int need, int want) {
- dTHX;
- i_reader_data *rd = (i_reader_data *)userdata;
- int count;
- int result;
- SV *data;
- dSP; dTARG = sv_newmortal();
- /* thanks to Simon Cozens for help with the dTARG above */
-
- ENTER;
- SAVETMPS;
- EXTEND(SP, 2);
- PUSHMARK(SP);
- PUSHi(want);
- PUSHi(need);
- PUTBACK;
-
- count = perl_call_sv(rd->sv, G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Result of perl_call_sv(..., G_SCALAR) != 1");
-
- data = POPs;
-
- if (SvOK(data)) {
- STRLEN len;
- char *ptr = SvPV(data, len);
- if (len > want)
- croak("Too much data returned in reader callback");
-
- memcpy(buffer, ptr, len);
- result = len;
- }
- else {
- result = -1;
- }
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return result;
-}
-
-typedef struct
-{
- SV *sv; /* a coderef or sub name */
-} i_writer_data;
-
-/* used by functions that want callbacks */
-static int write_callback(char *userdata, char const *data, int size) {
- dTHX;
- i_writer_data *wd = (i_writer_data *)userdata;
- int count;
- int success;
- SV *sv;
- dSP;
-
- ENTER;
- SAVETMPS;
- EXTEND(SP, 1);
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
- PUTBACK;
-
- count = perl_call_sv(wd->sv, G_SCALAR);
-
- SPAGAIN;
-
- if (count != 1)
- croak("Result of perl_call_sv(..., G_SCALAR) != 1");
-
- sv = POPs;
- success = SvTRUE(sv);
-
-
- PUTBACK;
- FREETMPS;
- LEAVE;
-
- return success;
-}
-
#define CBDATA_BUFSIZE 8192
struct cbdata {
@@ -873,7 +781,7 @@ validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
typedef i_int_hlines *Imager__Internal__Hlines;
static i_int_hlines *
-i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
+i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
i_int_init_hlines(result, start_y, count_y, start_x, count_x);
@@ -906,9 +814,9 @@ static int seg_compare(const void *vleft, const void *vright) {
static SV *
i_int_hlines_dump(i_int_hlines *hlines) {
dTHX;
- SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
- hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
- int y;
+ SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
+ i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
+ i_img_dim y;
for (y = hlines->start_y; y < hlines->limit_y; ++y) {
i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
@@ -918,10 +826,10 @@ i_int_hlines_dump(i_int_hlines *hlines) {
if (entry->count)
qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
- sv_catpvf(dump, " %d (%d):", y, entry->count);
+ sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
for (i = 0; i < entry->count; ++i) {
- sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
- entry->segs[i].x_limit);
+ sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
+ i_DFc(entry->segs[i].x_limit));
}
sv_catpv(dump, "\n");
}
@@ -932,6 +840,24 @@ i_int_hlines_dump(i_int_hlines *hlines) {
#endif
+static off_t
+i_sv_off_t(pTHX_ SV *sv) {
+#if LSEEKSIZE > IVSIZE
+ return (off_t)SvNV(sv);
+#else
+ return (off_t)SvIV(sv);
+#endif
+}
+
+static SV *
+i_new_sv_off_t(pTHX_ off_t off) {
+#if LSEEKSIZE > IVSIZE
+ return newSVnv(off);
+#else
+ return newSViv(off);
+#endif
+}
+
static im_pl_ext_funcs im_perl_funcs =
{
IMAGER_PL_API_VERSION,
@@ -1085,8 +1011,8 @@ MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
Imager::ImgRaw
IIM_new(x,y,ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
void
@@ -1164,20 +1090,21 @@ io_slurp(ig)
undef_int
i_set_image_file_limits(width, height, bytes)
- int width
- int height
- int bytes
+ i_img_dim width
+ i_img_dim height
+ size_t bytes
void
i_get_image_file_limits()
PREINIT:
- int width, height, bytes;
+ i_img_dim width, height;
+ size_t bytes;
PPCODE:
if (i_get_image_file_limits(&width, &height, &bytes)) {
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(width)));
PUSHs(sv_2mortal(newSViv(height)));
- PUSHs(sv_2mortal(newSViv(bytes)));
+ PUSHs(sv_2mortal(newSVuv(bytes)));
}
MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
@@ -1206,10 +1133,10 @@ void
i_io_read(ig, buffer_sv, size)
Imager::IO ig
SV *buffer_sv
- int size
+ IV size
PREINIT:
void *buffer;
- int result;
+ ssize_t result;
PPCODE:
if (size <= 0)
croak("size negative in call to i_io_read()");
@@ -1237,11 +1164,11 @@ i_io_read(ig, buffer_sv, size)
void
i_io_read2(ig, size)
Imager::IO ig
- int size
+ IV size
PREINIT:
SV *buffer_sv;
void *buffer;
- int result;
+ ssize_t result;
PPCODE:
if (size <= 0)
croak("size negative in call to i_io_read2()");
@@ -1260,10 +1187,10 @@ i_io_read2(ig, size)
SvREFCNT_dec(buffer_sv);
}
-int
+off_t
i_io_seek(ig, position, whence)
Imager::IO ig
- long position
+ off_t position
int whence
int
@@ -1277,6 +1204,7 @@ i_io_DESTROY(ig)
int
i_io_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
@@ -1303,27 +1231,27 @@ i_img_new()
Imager::ImgRaw
i_img_empty(im,x,y)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::ImgRaw
i_img_empty_ch(im,x,y,ch)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
Imager::ImgRaw
i_sametype(im, x, y)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::ImgRaw
i_sametype_chans(im, x, y, channels)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int channels
int
@@ -1357,7 +1285,7 @@ void
i_img_info(im)
Imager::ImgRaw im
PREINIT:
- int info[4];
+ i_img_dim info[4];
PPCODE:
i_img_info(im,info);
EXTEND(SP, 4);
@@ -1423,67 +1351,67 @@ i_img_is_monochrome(im)
void
i_line(im,x1,y1,x2,y2,val,endp)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
int endp
void
i_line_aa(im,x1,y1,x2,y2,val,endp)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
int endp
void
i_box(im,x1,y1,x2,y2,val)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
void
i_box_filled(im,x1,y1,x2,y2,val)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color val
int
i_box_filledf(im,x1,y1,x2,y2,val)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::Color::Float val
void
i_box_cfill(im,x1,y1,x2,y2,fill)
Imager::ImgRaw im
- int x1
- int y1
- int x2
- int y2
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
Imager::FillHandle fill
void
i_arc(im,x,y,rad,d1,d2,val)
Imager::ImgRaw im
- int x
- int y
- float rad
- float d1
- float d2
+ i_img_dim x
+ i_img_dim y
+ double rad
+ double d1
+ double d2
Imager::Color val
void
@@ -1499,11 +1427,11 @@ i_arc_aa(im,x,y,rad,d1,d2,val)
void
i_arc_cfill(im,x,y,rad,d1,d2,fill)
Imager::ImgRaw im
- int x
- int y
- float rad
- float d1
- float d2
+ i_img_dim x
+ i_img_dim y
+ double rad
+ double d1
+ double d2
Imager::FillHandle fill
void
@@ -1520,9 +1448,9 @@ i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
void
i_circle_aa(im,x,y,rad,val)
Imager::ImgRaw im
- float x
- float y
- float rad
+ double x
+ double y
+ double rad
Imager::Color val
int
@@ -1547,8 +1475,8 @@ i_arc_out(im,x,y,rad,d1,d2,val)
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
int
@@ -1557,8 +1485,8 @@ i_arc_out_aa(im,x,y,rad,d1,d2,val)
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
@@ -1673,30 +1601,30 @@ i_poly_aa_cfill(im,xc,yc,fill)
undef_int
i_flood_fill(im,seedx,seedy,dcol)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::Color dcol
undef_int
i_flood_cfill(im,seedx,seedy,fill)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::FillHandle fill
undef_int
i_flood_fill_border(im,seedx,seedy,dcol, border)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::Color dcol
Imager::Color border
undef_int
i_flood_cfill_border(im,seedx,seedy,fill, border)
Imager::ImgRaw im
- int seedx
- int seedy
+ i_img_dim seedx
+ i_img_dim seedy
Imager::FillHandle fill
Imager::Color border
@@ -1705,24 +1633,24 @@ void
i_copyto(im,src,x1,y1,x2,y2,tx,ty)
Imager::ImgRaw im
Imager::ImgRaw src
- int x1
- int y1
- int x2
- int y2
- int tx
- int ty
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
+ i_img_dim tx
+ i_img_dim ty
void
i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
Imager::ImgRaw im
Imager::ImgRaw src
- int x1
- int y1
- int x2
- int y2
- int tx
- int ty
+ i_img_dim x1
+ i_img_dim y1
+ i_img_dim x2
+ i_img_dim y2
+ i_img_dim tx
+ i_img_dim ty
Imager::Color trans
Imager::ImgRaw
@@ -1734,23 +1662,23 @@ undef_int
i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
Imager::ImgRaw im
Imager::ImgRaw src
- int tx
- int ty
- int src_minx
- int src_miny
- int src_maxx
- int src_maxy
+ i_img_dim tx
+ i_img_dim ty
+ i_img_dim src_minx
+ i_img_dim src_miny
+ i_img_dim src_maxx
+ i_img_dim src_maxy
undef_int
i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
Imager::ImgRaw out
Imager::ImgRaw src
- int out_left
- int out_top
- int src_left
- int src_top
- int width
- int height
+ i_img_dim out_left
+ i_img_dim out_top
+ i_img_dim src_left
+ i_img_dim src_top
+ i_img_dim width
+ i_img_dim height
int combine
double opacity
@@ -1759,14 +1687,14 @@ i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left,
Imager::ImgRaw out
Imager::ImgRaw src
Imager::ImgRaw mask
- int out_left
- int out_top
- int src_left
- int src_top
- int mask_left
- int mask_top
- int width
- int height
+ i_img_dim out_left
+ i_img_dim out_top
+ i_img_dim src_left
+ i_img_dim src_top
+ i_img_dim mask_left
+ i_img_dim mask_top
+ i_img_dim width
+ i_img_dim height
int combine
double opacity
@@ -1851,8 +1779,8 @@ i_rotate_exact(im, amount, ...)
Imager::ImgRaw
i_matrix_transform(im, xsize, ysize, matrix, ...)
Imager::ImgRaw im
- int xsize
- int ysize
+ i_img_dim xsize
+ i_img_dim ysize
PREINIT:
double matrix[9];
AV *av;
@@ -1899,7 +1827,7 @@ i_gaussian(im,stdev)
void
i_unsharp_mask(im,stdev,scale)
Imager::ImgRaw im
- float stdev
+ double stdev
double scale
int
@@ -2040,9 +1968,6 @@ _is_color_object(sv)
OUTPUT:
RETVAL
-#ifdef HAVE_LIBT1
-#endif
-
#ifdef HAVE_LIBTT
@@ -2062,6 +1987,7 @@ TT_DESTROY(handle)
int
TT_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning */
RETVAL = 1;
OUTPUT:
RETVAL
@@ -2074,10 +2000,10 @@ undef_int
i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
Imager::Color cl
- float points
+ double points
SV * str_sv
int smooth
int utf8
@@ -2101,10 +2027,10 @@ undef_int
i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
int channel
- float points
+ double points
SV * str_sv
int smooth
int utf8
@@ -2127,11 +2053,12 @@ i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
void
i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
Imager::Font::TT handle
- float point
+ double point
SV* str_sv
int utf8
PREINIT:
- int cords[BOUNDING_BOX_COUNT],rc;
+ i_img_dim cords[BOUNDING_BOX_COUNT];
+ int rc;
char * str;
STRLEN len;
int i;
@@ -2157,8 +2084,8 @@ i_tt_has_chars(handle, text_sv, utf8)
char const *text;
STRLEN len;
char *work;
- int count;
- int i;
+ size_t count;
+ size_t i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
@@ -2188,12 +2115,12 @@ i_tt_face_name(handle)
Imager::Font::TT handle
PREINIT:
char name[255];
- int len;
+ size_t len;
PPCODE:
len = i_tt_face_name(handle, name, sizeof(name));
if (len) {
EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
+ PUSHs(sv_2mortal(newSVpv(name, len-1)));
}
void
@@ -2205,7 +2132,7 @@ i_tt_glyph_name(handle, text_sv, utf8 = 0)
char const *text;
STRLEN work_len;
size_t len;
- int outsize;
+ size_t outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
@@ -2281,8 +2208,8 @@ i_writeppm_wiol(im, ig)
Imager::ImgRaw
i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
Imager::IO ig
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int datachannels
int storechannels
int intrl
@@ -2330,20 +2257,20 @@ i_readtga_wiol(ig, length)
Imager::ImgRaw
i_scaleaxis(im,Value,Axis)
Imager::ImgRaw im
- float Value
+ double Value
int Axis
Imager::ImgRaw
i_scale_nn(im,scx,scy)
Imager::ImgRaw im
- float scx
- float scy
+ double scx
+ double scy
Imager::ImgRaw
i_scale_mixing(im, width, height)
Imager::ImgRaw im
- int width
- int height
+ i_img_dim width
+ i_img_dim height
Imager::ImgRaw
i_haar(im)
@@ -2377,8 +2304,8 @@ i_transform(im,opx,opy,parm)
Imager::ImgRaw im
PREINIT:
double* parm;
- int* opx;
- int* opy;
+ int *opx;
+ int *opy;
int opxl;
int opyl;
int parmlen;
@@ -2431,8 +2358,8 @@ i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
AV *av_in_imgs
int channels
PREINIT:
- int width;
- int height;
+ i_img_dim width;
+ i_img_dim height;
struct rm_op *ops;
STRLEN ops_len;
int ops_count;
@@ -2536,21 +2463,21 @@ i_bumpmap(im,bump,channel,light_x,light_y,strength)
Imager::ImgRaw im
Imager::ImgRaw bump
int channel
- int light_x
- int light_y
- int strength
+ i_img_dim light_x
+ i_img_dim light_y
+ i_img_dim strength
void
i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
Imager::ImgRaw im
Imager::ImgRaw bump
int channel
- int tx
- int ty
- float Lx
- float Ly
- float Lz
+ i_img_dim tx
+ i_img_dim ty
+ double Lx
+ double Ly
+ double Lz
float cd
float cs
float n
@@ -2568,14 +2495,14 @@ i_postlevels(im,levels)
void
i_mosaic(im,size)
Imager::ImgRaw im
- int size
+ i_img_dim size
void
i_watermark(im,wmark,tx,ty,pixdiff)
Imager::ImgRaw im
Imager::ImgRaw wmark
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
int pixdiff
@@ -2607,8 +2534,8 @@ i_gradgen(im, ...)
Imager::ImgRaw im
PREINIT:
int num;
- int *xo;
- int *yo;
+ i_img_dim *xo;
+ i_img_dim *yo;
i_color *ival;
int dmeasure;
int i;
@@ -2634,12 +2561,12 @@ i_gradgen(im, ...)
num = num <= av_len(ac) ? num : av_len(ac);
num++;
if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
- xo = mymalloc( sizeof(int) * num );
- yo = mymalloc( sizeof(int) * num );
+ xo = mymalloc( sizeof(i_img_dim) * num );
+ yo = mymalloc( sizeof(i_img_dim) * num );
ival = mymalloc( sizeof(i_color) * num );
for(i = 0; i<num; i++) {
- xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
- yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
+ xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
+ yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
sv = *av_fetch(ac, i, 0);
if ( !sv_derived_from(sv, "Imager::Color") ) {
free(axx); free(ayy); free(ac);
@@ -2755,8 +2682,8 @@ i_nearest_color(im, ...)
Imager::ImgRaw im
PREINIT:
int num;
- int *xo;
- int *yo;
+ i_img_dim *xo;
+ i_img_dim *yo;
i_color *ival;
int dmeasure;
int i;
@@ -2782,12 +2709,12 @@ i_nearest_color(im, ...)
num = num <= av_len(ac) ? num : av_len(ac);
num++;
if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
- xo = mymalloc( sizeof(int) * num );
- yo = mymalloc( sizeof(int) * num );
+ xo = mymalloc( sizeof(i_img_dim) * num );
+ yo = mymalloc( sizeof(i_img_dim) * num );
ival = mymalloc( sizeof(i_color) * num );
for(i = 0; i<num; i++) {
- xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
- yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
+ xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
+ yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
sv = *av_fetch(ac, i, 0);
if ( !sv_derived_from(sv, "Imager::Color") ) {
free(axx); free(ayy); free(ac);
@@ -2859,8 +2786,8 @@ DSO_call(handle,func_index,hv)
SV *
i_get_pixel(im, x, y)
Imager::ImgRaw im
- int x
- int y;
+ i_img_dim x
+ i_img_dim y;
PREINIT:
i_color *color;
CODE:
@@ -2880,14 +2807,14 @@ i_get_pixel(im, x, y)
int
i_ppix(im, x, y, cl)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::Color cl
Imager::ImgRaw
i_img_pal_new(x, y, channels, maxpal)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int channels
int maxpal
@@ -2920,9 +2847,9 @@ i_img_to_rgb(src)
void
i_gpal(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_palidx *work;
int count, i;
@@ -2952,8 +2879,8 @@ i_gpal(im, l, r, y)
int
i_ppal(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_palidx *work;
int i;
@@ -2976,8 +2903,8 @@ i_ppal(im, l, y, ...)
int
i_ppal_p(im, l, y, data)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
SV *data
PREINIT:
i_palidx const *work;
@@ -3126,14 +3053,14 @@ i_img_virtual(im)
void
i_gsamp(im, l, r, y, ...)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
int *chans;
int chan_count;
i_sample_t *data;
- int count, i;
+ i_img_dim count, i;
PPCODE:
if (items < 5)
croak("No channel numbers supplied to g_samp()");
@@ -3166,17 +3093,17 @@ i_gsamp(im, l, r, y, ...)
undef_neg_int
i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
int bits
AV *target
- int offset
+ STRLEN offset
PREINIT:
int *chans;
int chan_count;
unsigned *data;
- int count, i;
+ i_img_dim count, i;
CODE:
i_clear_error();
if (items < 8)
@@ -3204,8 +3131,8 @@ i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
undef_neg_int
i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
int bits
SV *channels_sv
AV *data_av
@@ -3214,10 +3141,10 @@ i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count
PREINIT:
int chan_count;
int *channels;
- int data_count;
- int data_used;
+ STRLEN data_count;
+ size_t data_used;
unsigned *data;
- int i;
+ ptrdiff_t i;
CODE:
i_clear_error();
if (SvOK(channels_sv)) {
@@ -3269,10 +3196,10 @@ i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count
Imager::ImgRaw
i_img_masked_new(targ, mask, x, y, w, h)
Imager::ImgRaw targ
- int x
- int y
- int w
- int h
+ i_img_dim x
+ i_img_dim y
+ i_img_dim w
+ i_img_dim h
PREINIT:
i_img *mask;
CODE:
@@ -3292,13 +3219,13 @@ i_img_masked_new(targ, mask, x, y, w, h)
int
i_plin(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_color *work;
- int i;
+ STRLEN i;
STRLEN len;
- int count;
+ size_t count;
CODE:
if (items > 3) {
if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
@@ -3336,21 +3263,21 @@ i_plin(im, l, y, ...)
int
i_ppixf(im, x, y, cl)
Imager::ImgRaw im
- int x
- int y
+ i_img_dim x
+ i_img_dim y
Imager::Color::Float cl
void
i_gsampf(im, l, r, y, ...)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
int *chans;
int chan_count;
i_fsample_t *data;
- int count, i;
+ i_img_dim count, i;
PPCODE:
if (items < 5)
croak("No channel numbers supplied to g_sampf()");
@@ -3383,13 +3310,13 @@ i_gsampf(im, l, r, y, ...)
int
i_plinf(im, l, y, ...)
Imager::ImgRaw im
- int l
- int y
+ i_img_dim l
+ i_img_dim y
PREINIT:
i_fcolor *work;
- int i;
+ i_img_dim i;
STRLEN len;
- int count;
+ size_t count;
CODE:
if (items > 3) {
if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
@@ -3428,8 +3355,8 @@ i_plinf(im, l, y, ...)
SV *
i_gpixf(im, x, y)
Imager::ImgRaw im
- int x
- int y;
+ i_img_dim x
+ i_img_dim y;
PREINIT:
i_fcolor *color;
CODE:
@@ -3448,12 +3375,12 @@ i_gpixf(im, x, y)
void
i_glin(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_color *vals;
- int count, i;
+ i_img_dim count, i;
PPCODE:
if (l < r) {
vals = mymalloc((r-l) * sizeof(i_color));
@@ -3480,12 +3407,12 @@ i_glin(im, l, r, y)
void
i_glinf(im, l, r, y)
Imager::ImgRaw im
- int l
- int r
- int y
+ i_img_dim l
+ i_img_dim r
+ i_img_dim y
PREINIT:
i_fcolor *vals;
- int count, i;
+ i_img_dim count, i;
i_fcolor zero;
PPCODE:
for (i = 0; i < MAXCHANNELS; ++i)
@@ -3515,8 +3442,8 @@ i_glinf(im, l, r, y)
Imager::ImgRaw
i_img_16_new(x, y, ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
Imager::ImgRaw
@@ -3525,8 +3452,8 @@ i_img_to_rgb16(im)
Imager::ImgRaw
i_img_double_new(x, y, ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
Imager::ImgRaw
@@ -3704,6 +3631,7 @@ IFILL_DESTROY(fill)
int
IFILL_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
@@ -3726,8 +3654,8 @@ i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
Imager::Color bg
int combine
int hatch
- int dx
- int dy
+ i_img_dim dx
+ i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
@@ -3747,8 +3675,8 @@ i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
Imager::Color::Float bg
int combine
int hatch
- int dx
- int dy
+ i_img_dim dx
+ i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
@@ -3765,8 +3693,8 @@ i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
Imager::FillHandle
i_new_fill_image(src, matrix, xoff, yoff, combine)
Imager::ImgRaw src
- int xoff
- int yoff
+ i_img_dim xoff
+ i_img_dim yoff
int combine
PREINIT:
double matrix[9];
@@ -3809,9 +3737,9 @@ i_int_hlines_testing()
Imager::Internal::Hlines
i_int_hlines_new(start_y, count_y, start_x, count_x)
- int start_y
+ i_img_dim start_y
int count_y
- int start_x
+ i_img_dim start_x
int count_x
Imager::Internal::Hlines
@@ -3821,9 +3749,9 @@ i_int_hlines_new_img(im)
void
i_int_hlines_add(hlines, y, minx, width)
Imager::Internal::Hlines hlines
- int y
- int minx
- int width
+ i_img_dim y
+ i_img_dim minx
+ i_img_dim width
void
i_int_hlines_DESTROY(hlines)
@@ -3835,7 +3763,6 @@ i_int_hlines_dump(hlines)
int
i_int_hlines_CLONE_SKIP(cls)
- SV *cls
#endif
View
1 JPEG/imexif.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <float.h>
#include <string.h>
+#include <stdio.h>
/*
=head1 NAME
View
15 JPEG/imjpeg.c
@@ -33,11 +33,15 @@ Reads and writes JPEG images
#include "jerror.h"
#include <errno.h>
#include <stdlib.h>
+#include <stdio.h>
+#include "imexif.h"
#define JPEG_APP13 0xED /* APP13 marker code */
#define JPEG_APP1 (JPEG_APP0 + 1)
#define JPGS 16384
+#define JPEG_DIM_MAX JPEG_MAX_DIMENSION
+
static unsigned char fake_eoi[]={(JOCTET) 0xFF,(JOCTET) JPEG_EOI};
/* Bad design right here */
@@ -99,7 +103,7 @@ wiol_fill_input_buffer(j_decompress_ptr cinfo) {
wiol_src_ptr src = (wiol_src_ptr) cinfo->src;
ssize_t nbytes; /* We assume that reads are "small" */
- mm_log((1,"wiol_fill_input_buffer(cinfo 0x%p)\n", cinfo));
+ mm_log((1,"wiol_fill_input_buffer(cinfo %p)\n", cinfo));
nbytes = src->data->readcb(src->data, src->buffer, JPGS);
@@ -214,7 +218,7 @@ wiol_empty_output_buffer(j_compress_ptr cinfo) {
ssize_t nbytes = JPGS - dest->pub.free_in_buffer;
*/
- mm_log((1,"wiol_empty_output_buffer(cinfo 0x%p)\n", cinfo));
+ mm_log((1,"wiol_empty_output_buffer(cinfo %p)\n", cinfo));
rc = dest->data->writecb(dest->data, dest->buffer, JPGS);
if (rc != JPGS) { /* XXX: Should raise some jpeg error */
@@ -392,7 +396,7 @@ i_readjpeg_wiol(io_glue *data, int length, char** iptc_itext, int *itlength) {
int channels;
volatile int src_set = 0;
- mm_log((1,"i_readjpeg_wiol(data 0x%p, length %d,iptc_itext 0x%p)\n", data, length, iptc_itext));
+ mm_log((1,"i_readjpeg_wiol(data %p, length %d,iptc_itext %p)\n", data, length, iptc_itext));
i_clear_error();
@@ -589,6 +593,11 @@ i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor) {
i_clear_error();
+ if (im->xsize > JPEG_DIM_MAX || im->ysize > JPEG_DIM_MAX) {
+ i_push_error(0, "image too large for JPEG");
+ return 0;
+ }
+
if (!(im->channels==1 || im->channels==3)) {
want_channels = im->channels - 1;
}
View
54 JPEG/t/t20limit.t
@@ -0,0 +1,54 @@
+#!perl -w
+use strict;
+use Imager;
+use Test::More tests => 12;
+
+my $max_dim = 65500;
+
+{
+ # JPEG files are limited to 0xFFFF x 0xFFFF pixels
+ # but libjpeg sets the limit lower to avoid overflows
+ {
+ my $im = Imager->new(xsize => 1+$max_dim, ysize => 1);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "jpeg"),
+ "fail to write too wide an image");
+ is($im->errstr, "image too large for JPEG",
+ "check error message");
+ }
+ SKIP:
+ {
+ my $im = Imager->new(xsize => $max_dim, ysize => 1);
+ $im->box(fill => { hatch => "check4x4" });
+ my $data = '';
+ ok($im->write(data => \$data, type => "jpeg"),
+ "write image at width limit")
+ or print "# ", $im->errstr, "\n";
+ my $im2 = Imager->new(data => $data, ftype => "jpeg");
+ ok($im2, "read it ok")
+ or skip("cannot load the wide image", 1);
+ is($im->getwidth, $max_dim, "check width");
+ is($im->getheight, 1, "check height");
+ }
+ {
+ my $im = Imager->new(xsize => 1, ysize => 1+$max_dim);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "jpeg"),
+ "fail to write too tall an image");
+ is($im->errstr, "image too large for JPEG",
+ "check error message"