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
===========
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;
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);
int
FT2_CLONE_SKIP(...)
CODE:
+ (void)items;
RETVAL = 1;
OUTPUT:
RETVAL
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;
int vlayout
int utf8
PREINIT:
- int bbox[8];
+ i_img_dim bbox[8];
int i;
PPCODE:
#ifdef SvUTF8
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
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
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);
char *text;
STRLEN len;
char *work;
- int count;
- int i;
+ size_t count;
+ size_t i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
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) {
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;
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)
}
/*
-=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.
*/
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;
=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;
=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]);
}
/*
-=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.
*/
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;
=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;
*/
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;
=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",
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);
#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;
}
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,
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
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);
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
/*
=head1 NAME
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
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];
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) {
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_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;
--- /dev/null
+#!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");
+}
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;
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;
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;
}
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;
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;
}
-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 {
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);
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];
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");
}
#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,
Imager::ImgRaw
IIM_new(x,y,ch)
- int x
- int y
+ i_img_dim x
+ i_img_dim y
int ch
void
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_
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()");
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()");
SvREFCNT_dec(buffer_sv);
}
-int
+off_t
i_io_seek(ig, position, whence)
Imager::IO ig
- long position
+ off_t position
int whence
int
int
i_io_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
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
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);
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
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
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
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
int
i_img_dim x
i_img_dim y
i_img_dim rad
- float d1
- float d2
+ double d1
+ double d2
Imager::Color val
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
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
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
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
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;
void
i_unsharp_mask(im,stdev,scale)
Imager::ImgRaw im
- float stdev
+ double stdev
double scale
int
OUTPUT:
RETVAL
-#ifdef HAVE_LIBT1
-#endif
-
#ifdef HAVE_LIBTT
int
TT_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning */
RETVAL = 1;
OUTPUT:
RETVAL
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
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
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;
char const *text;
STRLEN len;
char *work;
- int count;
- int i;
+ size_t count;
+ size_t i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
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
char const *text;
STRLEN work_len;
size_t len;
- int outsize;
+ size_t outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
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
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)
Imager::ImgRaw im
PREINIT:
double* parm;
- int* opx;
- int* opy;
+ int *opx;
+ int *opy;
int opxl;
int opyl;
int parmlen;
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;
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
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
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
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;
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);
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;
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);
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:
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
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;
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;
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;
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()");
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)
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
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)) {
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:
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))) {
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()");
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))) {
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:
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));
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)
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
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
int
IFILL_CLONE_SKIP(...)
CODE:
+ (void)items; /* avoid unused warning for XS variable */
RETVAL = 1;
OUTPUT:
RETVAL
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;
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;
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];
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
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)
int
i_int_hlines_CLONE_SKIP(cls)
- SV *cls
#endif
#include <stdlib.h>
#include <float.h>
#include <string.h>
+#include <stdio.h>
/*
=head1 NAME
#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 */
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);
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 */
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();
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;
}
--- /dev/null
+#!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");
+ }
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 1, ysize => $max_dim);
+ $im->box(fill => { hatch => "check2x2" });
+ my $data = '';
+ ok($im->write(data => \$data, type => "jpeg"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "jpeg");
+ ok($im2, "read it ok")
+ or skip("cannot load the wide image", 1);
+ is($im->getwidth, 1, "check width");
+ is($im->getheight, $max_dim, "check height");
+ }
+}
GIF/t/t10gif.t
GIF/t/t20new.t
GIF/t/t30fixed.t
+GIF/t/t40limit.t
GIF/testimg/badindex.gif GIF with a bad color index
GIF/testimg/bandw.gif
GIF/testimg/expected.gif
JPEG/README
JPEG/t/t00load.t
JPEG/t/t10jpeg.t Test jpeg support
+JPEG/t/t20limit.t
JPEG/testimg/209_yonge.jpg Regression test: #17981
JPEG/testimg/exiftest.jpg Test image for EXIF parsing
JPEG/testimg/scmyk.jpg Simple CMYK JPEG image
SGI/t/00load.t
SGI/t/10read.t
SGI/t/20write.t
+SGI/t/30limit.t Test size limit checking
SGI/testimg/rle.rgb
SGI/testimg/rle12.rgb
SGI/testimg/rle16.rgb
testimg/test.raw Standard test image as RAW
testimg/test.tga Standard test image as TGA
testimg/test_gimp_pal A simple GIMP palette file
+testimg/tootall.ppm
+testimg/toowide.ppm
testimg/winrgb2.bmp 1-bit bmp base
testimg/winrgb24.bmp 24-bit bmp base
testimg/winrgb24off.bmp 24-bit bmp with image data offset from header
}
print CONFIG "#define $define->[0] $define->[1]\n";
}
+ if ($Config{gccversion} && $Config{gccversion} > 3) {
+ print CONFIG <<EOS;
+/*
+
+Compiler supports the GCC __attribute__((format...)) syntax.
+
+*/
+
+#define IMAGER_FORMAT_ATTR 1
+EOS
+ }
+
+ print CONFIG <<EOS;
+/*
+ Type and format code for formatted output as with printf.
+
+ This is intended for formatting i_img_dim values.
+*/
+typedef $Config{ivtype} i_dim_format_t;
+#define i_DF $Config{ivdformat}
+EOS
+
print CONFIG "\n#endif\n";
close CONFIG;
}
void
mandelbrot(i_img *im, double minx, double miny, double maxx, double maxy, int max_iter) {
- int i,x,y;
+ int i;
+ i_img_dim x,y;
int idx;
double divx, divy;
int aspect_only, have_res;
mm_log((1,"i_writepng(im %p ,ig %p)\n", im, ig));
-
+
+ i_clear_error();
+
+ if (im->xsize > PNG_UINT_31_MAX || im->ysize > PNG_UINT_31_MAX) {
+ i_push_error(0, "image too large for PNG");
+ return 0;
+ }
+
height = im->ysize;
width = im->xsize;
/* we add that little bit to avoid rounding issues */
#define SampleFTo16(num) ((int)((num) * 65535.0 + 0.01))
+/* maximum size of an SGI image */
+#define SGI_DIM_LIMIT 0xFFFF
+
typedef struct {
unsigned short imagic;
unsigned char storagetype;
i_clear_error();
+ if (img->xsize > SGI_DIM_LIMIT || img->ysize > SGI_DIM_LIMIT) {
+ i_push_error(0, "image too large for SGI");
+ return 0;
+ }
+
if (!write_sgi_header(img, ig, &rle, &bpc2))
return 0;
--- /dev/null
+#!perl -w
+use Imager;
+use Test::More tests => 14;
+use Imager::Test qw(is_image);
+
+{
+ # SGI files are limited to 0xFFFF x 0xFFFF pixels
+ {
+ my $im = Imager->new(xsize => 0x10000, ysize => 1);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "sgi"),
+ "fail to write too wide an image");
+ is($im->errstr, "image too large for SGI",
+ "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 => "sgi"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "sgi");
+ 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 => "sgi"),
+ "fail to write too tall an image");
+ is($im->errstr, "image too large for SGI",
+ "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 => "sgi"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "sgi");
+ 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");
+ }
+}
undef_int
i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
int channel
int fontnum
- float points
+ double points
SV* str_sv
int align
int utf8
void
i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
int fontnum
- float point
+ double point
SV* str_sv
int utf8
char* flags
PREINIT:
char *str;
STRLEN len;
- int cords[BOUNDING_BOX_COUNT];
+ i_img_dim cords[BOUNDING_BOX_COUNT];
int i;
int rc;
PPCODE:
undef_int
i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
Imager::ImgRaw im
- int xb
- int yb
+ i_img_dim xb
+ i_img_dim yb
Imager::Color cl
int fontnum
- float points
+ double points
SV* str_sv
int align
int utf8
*/
undef_int
-i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,size_t len,int align, int utf8, char const *flags) {
+i_t1_cp(i_img *im,i_img_dim xb,i_img_dim yb,int channel,int fontnum,double points,char* str,size_t len,int align, int utf8, char const *flags) {
GLYPH *glyph;
int xsize,ysize,x,y;
i_color val;
*/
int
-i_t1_bbox(int fontnum,float points,const char *str,size_t len,int cords[6], int utf8,char const *flags) {
+i_t1_bbox(int fontnum, double points,const char *str,size_t len, i_img_dim cords[6], int utf8,char const *flags) {
BBox bbox;
BBox gbbox;
int mod_flags = t1_get_flags(flags);
- int advance;
+ i_img_dim advance;
int space_position = T1_GetEncodingIndex(fontnum, "space");
mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len));
(int)(bbox.ury*points/1000) ));
- cords[BBOX_NEG_WIDTH]=((float)bbox.llx*points)/1000;
- cords[BBOX_POS_WIDTH]=((float)bbox.urx*points)/1000;
+ cords[BBOX_NEG_WIDTH]=((double)bbox.llx*points)/1000;
+ cords[BBOX_POS_WIDTH]=((double)bbox.urx*points)/1000;
- cords[BBOX_GLOBAL_DESCENT]=((float)gbbox.lly*points)/1000;
- cords[BBOX_GLOBAL_ASCENT]=((float)gbbox.ury*points)/1000;
+ cords[BBOX_GLOBAL_DESCENT]=((double)gbbox.lly*points)/1000;
+ cords[BBOX_GLOBAL_ASCENT]=((double)gbbox.ury*points)/1000;
- cords[BBOX_DESCENT]=((float)bbox.lly*points)/1000;
- cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000;
+ cords[BBOX_DESCENT]=((double)bbox.lly*points)/1000;
+ cords[BBOX_ASCENT]=((double)bbox.ury*points)/1000;
- cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000;
+ cords[BBOX_ADVANCE_WIDTH] = ((double)advance * points)/1000;
cords[BBOX_RIGHT_BEARING] =
cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
*/
undef_int
-i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,size_t len,int align, int utf8, char const *flags) {
+i_t1_text(i_img *im, i_img_dim xb, i_img_dim yb,const i_color *cl,int fontnum, double points,const char* str,size_t len,int align, int utf8, char const *flags) {
GLYPH *glyph;
int xsize,ysize,y;
int mod_flags = t1_get_flags(flags);
static char *
t1_from_utf8(char const *in, size_t len, int *outlen) {
- /* at this point len is from a perl SV, so can't approach MAXINT */
- char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */
+ /* at this point len is from a STRLEN which should be size_t and can't
+ be too big for mymalloc */
+ char *out = mymalloc(len+1); /* rechecked 29jul11 tonyc */
char *p = out;
unsigned long c;
i_t1_set_aa(int st);
extern undef_int
-i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,size_t len,int align, int utf8, char const *flags);
+i_t1_cp(i_img *im,i_img_dim xb,i_img_dim yb,int channel,int fontnum,double points,char* str,size_t len,int align, int utf8, char const *flags);
extern int
-i_t1_bbox(int fontnum,float points,const char *str,size_t len,int cords[6], int utf8,char const *flags);
+i_t1_bbox(int fontnum,double points,const char *str,size_t len,i_img_dim *cords, int utf8,char const *flags);
extern undef_int
-i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,size_t len,int align, int utf8, char const *flags);
+i_t1_text(i_img *im,i_img_dim xb,i_img_dim yb,const i_color *cl,int fontnum,double points,const char* str,size_t len,int align, int utf8, char const *flags);
extern int
i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
uint32 tag;
};
-static i_img *read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete);
-static i_img *read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete);
+static i_img *read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete);
+static i_img *read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete);
static struct tag_name text_tag_names[] =
{
the raster buffer, (for tiles against the right side of the
image) */
-typedef int (*read_putter_t)(read_state_t *state, int x, int y, int width,
- int height, int extras);
+typedef int (*read_putter_t)(read_state_t *state, i_img_dim x, i_img_dim y,
+ i_img_dim width, i_img_dim height, int extras);
/* reads from a tiled or strip image and calls the putter.
This may need a second type for handling non-contiguous images
TIFF *tif;
i_img *img;
void *raster;
- unsigned long pixels_read;
+ i_img_dim pixels_read;
int allow_incomplete;
void *line_buf;
uint32 width, height;
static int strip_contig_getter(read_state_t *state, read_putter_t putter);
static int setup_paletted(read_state_t *state);
-static int paletted_putter8(read_state_t *, int, int, int, int, int);
-static int paletted_putter4(read_state_t *, int, int, int, int, int);
+static int paletted_putter8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
+static int paletted_putter4(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_16_rgb(read_state_t *state);
static int setup_16_grey(read_state_t *state);
-static int putter_16(read_state_t *, int, int, int, int, int);
+static int putter_16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_8_rgb(read_state_t *state);
static int setup_8_grey(read_state_t *state);
-static int putter_8(read_state_t *, int, int, int, int, int);
+static int putter_8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_32_rgb(read_state_t *state);
static int setup_32_grey(read_state_t *state);
-static int putter_32(read_state_t *, int, int, int, int, int);
+static int putter_32(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_bilevel(read_state_t *state);
-static int putter_bilevel(read_state_t *, int, int, int, int, int);
+static int putter_bilevel(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_cmyk8(read_state_t *state);
-static int putter_cmyk8(read_state_t *, int, int, int, int, int);
+static int putter_cmyk8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static int setup_cmyk16(read_state_t *state);
-static int putter_cmyk16(read_state_t *, int, int, int, int, int);
+static int putter_cmyk16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
static const int text_tag_count =
sizeof(text_tag_names) / sizeof(*text_tag_names);
static int save_tiff_tags(TIFF *tif, i_img *im);
static void
-pack_4bit_to(unsigned char *dest, const unsigned char *src, int count);
+pack_4bit_to(unsigned char *dest, const unsigned char *src, i_img_dim count);
static toff_t sizeproc(thandle_t x) {
getterf = strip_contig_getter;
}
if (setupf && getterf && putterf) {
- unsigned long total_pixels = (unsigned long)width * height;
+ i_img_dim total_pixels = width * height;
memset(&state, 0, sizeof(state));
state.tif = tif;
state.allow_incomplete = allow_incomplete;
width = im->xsize;
height = im->ysize;
+ if (width != im->xsize || height != im->ysize) {
+ i_push_error(0, "image too large for TIFF");
+ return 0;
+ }
+
switch (im->channels) {
case 1:
case 2:
unsigned char *in_row;
unsigned char *out_row;
unsigned out_size;
- int x, y;
+ i_img_dim x, y;
int invert;
mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
unsigned char *out_row;
unsigned out_size;
- int y;
+ i_img_dim y;
mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
unsigned char *in_row;
unsigned char *out_row;
- unsigned out_size;
- int y;
+ size_t out_size;
+ i_img_dim y;
mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
unsigned *in_row;
size_t out_size;
uint32 *out_row;
- int y;
+ i_img_dim y;
size_t sample_count = im->xsize * im->channels;
size_t sample_index;
unsigned *in_row;
size_t out_size;
uint16 *out_row;
- int y;
+ i_img_dim y;
size_t sample_count = im->xsize * im->channels;
size_t sample_index;
uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
size_t out_size;
unsigned char *out_row;
- int y;
+ i_img_dim y;
size_t sample_count = im->xsize * im->channels;
mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
height = im->ysize;
channels = im->channels;
+ if (width != im->xsize || height != im->ysize) {
+ i_push_error(0, "image too large for TIFF");
+ return 0;
+ }
+
mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
if (im->type == i_palette_type) {
mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
old_handler = TIFFSetErrorHandler(error_handler);
i_clear_error();
- mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
+ mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
ig, imgs, count));
/* FIXME: Enable the mmap interface */
old_handler = TIFFSetErrorHandler(error_handler);
i_clear_error();
- mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
+ mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
ig, imgs, count));
/* FIXME: Enable the mmap interface */
old_handler = TIFFSetErrorHandler(error_handler);
i_clear_error();
- mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
+ mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig));
/* FIXME: Enable the mmap interface */
old_handler = TIFFSetErrorHandler(error_handler);
i_clear_error();
- mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", im, ig));
+ mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig));
/* FIXME: Enable the mmap interface */
static void
unpack_4bit_to(unsigned char *dest, const unsigned char *src,
- int src_byte_count) {
+ size_t src_byte_count) {
while (src_byte_count > 0) {
*dest++ = *src >> 4;
*dest++ = *src++ & 0xf;
}
static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
- int pixel_count) {
+ i_img_dim pixel_count) {
int i = 0;
while (i < pixel_count) {
if ((i & 1) == 0) {
}
static i_img *
-make_rgb(TIFF *tif, int width, int height, int *alpha_chan) {
+make_rgb(TIFF *tif, i_img_dim width, i_img_dim height, int *alpha_chan) {
uint16 photometric;
uint16 channels, in_channels;
uint16 extra_count;
}
static i_img *
-read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete) {
+read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
i_img *im;
uint32* raster = NULL;
uint32 rowsperstrip, row;
}
static i_img *
-read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete) {
+read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
i_img *im;
uint32* raster = NULL;
int ok = 1;
}
static int
-paletted_putter8(read_state_t *state, int x, int y, int width, int height, int extras) {
+paletted_putter8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
unsigned char *p = state->raster;
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
i_ppal(state->img, x, x + width, y, p);
p += width + extras;
}
static int
-paletted_putter4(read_state_t *state, int x, int y, int width, int height, int extras) {
+paletted_putter4(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
uint32 img_line_size = (width + 1) / 2;
uint32 skip_line_size = (width + extras + 1) / 2;
unsigned char *p = state->raster;
if (!state->line_buf)
state->line_buf = mymalloc(state->width);
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
unpack_4bit_to(state->line_buf, p, img_line_size);
i_ppal(state->img, x, x + width, y, state->line_buf);
}
static int
-putter_16(read_state_t *state, int x, int y, int width, int height,
+putter_16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
uint16 *p = state->raster;
int out_chan = state->img->channels;
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
int ch;
unsigned *outp = state->line_buf;
}
static int
-putter_8(read_state_t *state, int x, int y, int width, int height,
+putter_8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
unsigned char *p = state->raster;
int out_chan = state->img->channels;
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
int ch;
i_color *outp = state->line_buf;
}
static int
-putter_32(read_state_t *state, int x, int y, int width, int height,
+putter_32(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
uint32 *p = state->raster;
int out_chan = state->img->channels;
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
int ch;
i_fcolor *outp = state->line_buf;
}
static int
-putter_bilevel(read_state_t *state, int x, int y, int width, int height,
+putter_bilevel(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
unsigned char *line_in = state->raster;
size_t line_size = (width + row_extras + 7) / 8;
/* tifflib returns the bits in MSB2LSB order even when the file is
in LSB2MSB, so we only need to handle MSB2LSB */
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
unsigned char *outp = state->line_buf;
unsigned char *inp = line_in;
unsigned mask = 0x80;
}
static int
-putter_cmyk8(read_state_t *state, int x, int y, int width, int height,
+putter_cmyk8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
unsigned char *p = state->raster;
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
int ch;
i_color *outp = state->line_buf;
}
static int
-putter_cmyk16(read_state_t *state, int x, int y, int width, int height,
+putter_cmyk16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
int row_extras) {
uint16 *p = state->raster;
int out_chan = state->img->channels;
mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
- state->pixels_read += (unsigned long) width * height;
+ state->pixels_read += width * height;
while (height > 0) {
- int i;
+ i_img_dim i;
int ch;
unsigned *outp = state->line_buf;
$input{'y'}, $input{color}, $input{size},
$input{string}, $input{align}, $input{aa}, $input{utf8});
}
+
+ return 1;
}
void
i_wf_bbox(face, size, text_sv, utf8=0)
- char *face
- int size
+ const char *face
+ i_img_dim size
SV *text_sv
int utf8
PREINIT:
- int cords[BOUNDING_BOX_COUNT];
+ i_img_dim cords[BOUNDING_BOX_COUNT];
int rc, i;
char const *text;
STRLEN text_len;
undef_int
i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
- char *face
+ const char *face
Imager::ImgRaw im
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
Imager::Color cl
- int size
+ i_img_dim size
SV *text_sv
int align
int aa
undef_int
i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
- char *face
+ const char *face
Imager::ImgRaw im
- int tx
- int ty
+ i_img_dim tx
+ i_img_dim ty
int channel
- int size
+ i_img_dim size
SV *text_sv
int align
int aa
#include "imdatatypes.h"
-extern int i_wf_bbox(const char *face, int size, const char *text, int length, int *bbox, int utf8);
-extern int i_wf_text(const char *face, i_img *im, int tx, int ty, const i_color *cl,
- int size, const char *text, int len, int align, int aa, int utf8);
-extern int i_wf_cp(const char *face, i_img *im, int tx, int ty, int channel,
- int size, const char *text, int len, int align, int aa, int utf8);
+extern int i_wf_bbox(const char *face, i_img_dim size, const char *text, size_t length, i_img_dim *bbox, int utf8);
+extern int i_wf_text(const char *face, i_img *im, i_img_dim tx, i_img_dim ty, const i_color *cl,
+ i_img_dim size, const char *text, size_t len, int align, int aa, int utf8);
+extern int i_wf_cp(const char *face, i_img *im, i_img_dim tx, i_img_dim ty, int channel,
+ i_img_dim size, const char *text, size_t len, int align, int aa, int utf8);
extern int i_wf_addfont(char const *file);
extern int i_wf_delfont(char const *file);
=head1 SYNOPSIS
- int bbox[6];
+ i_img_dim bbox[6];
if (i_wf_bbox(facename, size, text, text_len, bbox)) {
// we have the bbox
}
static void set_logfont(const char *face, int size, LOGFONT *lf);
static LPVOID render_text(const char *face, int size, const char *text, int length, int aa,
- HBITMAP *pbm, SIZE *psz, TEXTMETRIC *tm, int *bbox, int utf8);
+ HBITMAP *pbm, SIZE *psz, TEXTMETRIC *tm, i_img_dim *bbox, int utf8);
static LPWSTR utf8_to_wide_string(char const *text, int text_len, int *wide_chars);
/*
=cut
*/
-int i_wf_bbox(const char *face, int size, const char *text, int length, int *bbox,
- int utf8) {
+int i_wf_bbox(const char *face, i_img_dim size, const char *text, size_t length,
+ i_img_dim *bbox, int utf8) {
LOGFONT lf;
HFONT font, oldFont;
HDC dc;
int got_first_ch = 0;
unsigned long first_ch, last_ch;
+ i_clear_error();
+
mm_log((1, "i_wf_bbox(face %s, size %d, text %p, length %d, bbox %p, utf8 %d)\n", face, size, text, length, bbox, utf8));
set_logfont(face, size, &lf);
ReleaseDC(NULL, dc);
DeleteObject(font);
- mm_log((1, " bbox=> negw=%d glob_desc=%d pos_wid=%d glob_asc=%d desc=%d asc=%d adv_width=%d rightb=%d\n", bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5], bbox[6], bbox[7]));
+ mm_log((1, " bbox=> negw=%" i_DF " glob_desc=%" i_DF " pos_wid=%" i_DF
+ " glob_asc=%" i_DF " desc=%" i_DF " asc=%" i_DF " adv_width=%" i_DF
+ " rightb=%" i_DF "\n", i_DFc(bbox[0]), i_DFc(bbox[1]), i_DFc(bbox[2]),
+ i_DFc(bbox[3]), i_DFc(bbox[4]), i_DFc(bbox[5]), i_DFc(bbox[6]),
+ i_DFc(bbox[7])));
return BBOX_RIGHT_BEARING + 1;
}
*/
int
-i_wf_text(const char *face, i_img *im, int tx, int ty, const i_color *cl, int size,
- const char *text, int len, int align, int aa, int utf8) {
+i_wf_text(const char *face, i_img *im, i_img_dim tx, i_img_dim ty, const i_color *cl, i_img_dim size,
+ const char *text, size_t len, int align, int aa, int utf8) {
unsigned char *bits;
HBITMAP bm;
SIZE sz;
- int line_width;
- int x, y;
+ i_img_dim line_width;
+ i_img_dim x, y;
int ch;
TEXTMETRIC tm;
int top;
- int bbox[BOUNDING_BOX_COUNT];
+ i_img_dim bbox[BOUNDING_BOX_COUNT];
+
+ i_clear_error();
- mm_log((1, "i_wf_text(face %s, im %p, tx %d, ty %d, cl %p, size %d, text %p, length %d, align %d, aa %d, utf8 %d)\n", face, im, tx, ty, cl, size, text, len, align, aa, aa, utf8));
+ mm_log((1, "i_wf_text(face %s, im %p, tx %" i_DF ", ty %" i_DF ", cl %p, size %" i_DF ", text %p, length %lu, align %d, aa %d, utf8 %d)\n", face, im, i_DFcp(tx, ty), cl, i_DFc(size), text, (unsigned long)len, align, aa, aa, utf8));
if (!i_wf_bbox(face, size, text, len, bbox, utf8))
return 0;
*/
int
-i_wf_cp(const char *face, i_img *im, int tx, int ty, int channel, int size,
- const char *text, int len, int align, int aa, int utf8) {
+i_wf_cp(const char *face, i_img *im, i_img_dim tx, i_img_dim ty, int channel, i_img_dim size,
+ const char *text, size_t len, int align, int aa, int utf8) {
unsigned char *bits;
HBITMAP bm;
SIZE sz;
int line_width;
- int x, y;
+ i_img_dim x, y;
TEXTMETRIC tm;
- int top;
- int bbox[BOUNDING_BOX_COUNT];
+ i_img_dim top;
+ i_img_dim bbox[BOUNDING_BOX_COUNT];
+
+ i_clear_error();
- mm_log((1, "i_wf_cp(face %s, im %p, tx %d, ty %d, channel %d, size %d, text %p, length %d, align %d, aa %d, utf8 %d)\n", face, im, tx, ty, channel, size, text, len, align, aa, aa, utf8));
+ mm_log((1, "i_wf_cp(face %s, im %p, tx %" i_DF ", ty %" i_DF ", channel %d, size %" i_DF ", text %p, length %lu, align %d, aa %d, utf8 %d)\n", face, im, i_DFcp(tx, ty), channel, i_DFc(size), text, (unsigned long)len, align, aa, aa, utf8));
if (!i_wf_bbox(face, size, text, len, bbox, utf8))
return 0;
=cut
*/
static LPVOID render_text(const char *face, int size, const char *text, int length, int aa,
- HBITMAP *pbm, SIZE *psz, TEXTMETRIC *tm, int *bbox, int utf8) {
+ HBITMAP *pbm, SIZE *psz, TEXTMETRIC *tm, i_img_dim *bbox, int utf8) {
BITMAPINFO bmi;
BITMAPINFOHEADER *bmih = &bmi.bmiHeader;
HDC dc, bmpDc;
$category = $1;
}
elsif (/^=synopsis (.*)/) {
+ unless (length $synopsis) {
+ push @funcdocs, "\n";
+ }
$synopsis .= "$1\n";
+ push @funcdocs, " $1\n";
}
elsif (/^=order (.*)$/) {
$order = $1;
sub make_func_list {
- my @funcs = qw(i_img i_color i_fcolor i_fill_t mm_log i_img_color_channels i_img_has_alpha i_img_dim);
+ my @funcs = qw(i_img i_color i_fcolor i_fill_t mm_log i_img_color_channels i_img_has_alpha i_img_dim i_DF i_DFc i_DFp i_DFcp);
open FUNCS, "< imexttypes.h"
or die "Cannot open imexttypes.h: $!\n";
my $in_struct;
#define BMPRLE_ENDOFBMP 1
#define BMPRLE_DELTA 2
+#define SIGNBIT32 ((i_upacked_t)1U << 31)
+#define SIGNBIT16 ((i_upacked_t)1U << 15)
+
+#define SIGNMAX32 ((1UL << 31) - 1)
+
static int read_packed(io_glue *ig, char *format, ...);
static int write_packed(io_glue *ig, char *format, ...);
static int write_bmphead(io_glue *ig, i_img *im, int bit_count,
int bit_count, int clr_used, int compression,
long offbits, int allow_incomplete);
+/* used for the read_packed() and write_packed() functions, an integer
+ * type */
+typedef long i_packed_t;
+typedef unsigned long i_upacked_t;
+
/*
=item i_writebmp_wiol(im, io_glue)
i_img *
i_readbmp_wiol(io_glue *ig, int allow_incomplete) {
- int b_magic, m_magic, filesize, res1, res2, infohead_size;
- int xsize, ysize, planes, bit_count, compression, size_image, xres, yres;
- int clr_used, clr_important, offbits;
+ i_packed_t b_magic, m_magic, filesize, res1, res2, infohead_size;
+ i_packed_t xsize, ysize, planes, bit_count, compression, size_image, xres, yres;
+ i_packed_t clr_used, clr_important, offbits;
i_img *im;
mm_log((1, "i_readbmp_wiol(ig %p)\n", ig));
io_glue_commit_types(ig);
i_clear_error();
- if (!read_packed(ig, "CCVvvVVVVvvVVVVVV", &b_magic, &m_magic, &filesize,
+ if (!read_packed(ig, "CCVvvVVV!V!vvVVVVVV", &b_magic, &m_magic, &filesize,
&res1, &res2, &offbits, &infohead_size,
&xsize, &ysize, &planes,
&bit_count, &compression, &size_image, &xres, &yres,
mm_log((1, " bmp header: filesize %d offbits %d xsize %d ysize %d planes %d "
"bit_count %d compression %d size %d xres %d yres %d clr_used %d "
- "clr_important %d\n", filesize, offbits, xsize, ysize, planes,
- bit_count, compression, size_image, xres, yres, clr_used,
- clr_important));
+ "clr_important %d\n", (int)filesize, (int)offbits, (int)xsize,
+ (int)ysize, (int)planes, (int)bit_count, (int)compression,
+ (int)size_image, (int)xres, (int)yres, (int)clr_used,
+ (int)clr_important));
if (!i_int_check_image_file_limits(xsize, abs(ysize), 3, sizeof(i_sample_t))) {
mm_log((1, "i_readbmp_wiol: image size exceeds limits\n"));
break;
default:
- i_push_errorf(0, "unknown bit count for BMP file (%d)", bit_count);
+ i_push_errorf(0, "unknown bit count for BMP file (%d)", (int)bit_count);
return NULL;
}
=cut
*/
-static
-int read_packed(io_glue *ig, char *format, ...) {
+static int
+read_packed(io_glue *ig, char *format, ...) {
unsigned char buf[4];
va_list ap;
- int *p;
+ i_packed_t *p;
+ i_packed_t work;
+ int code;
+ int shrieking; /* format code has a ! flag */
va_start(ap, format);
while (*format) {
- p = va_arg(ap, int *);
+ p = va_arg(ap, i_packed_t *);
- switch (*format) {
+ code = *format++;
+ shrieking = *format == '!';
+ if (shrieking) ++format;
+
+ switch (code) {
case 'v':
if (ig->readcb(ig, buf, 2) != 2)
return 0;
- *p = buf[0] + (buf[1] << 8);
+ work = buf[0] + ((i_packed_t)buf[1] << 8);
+ if (shrieking)
+ *p = (work ^ SIGNBIT16) - SIGNBIT16;
+ else
+ *p = work;
break;
case 'V':
if (ig->readcb(ig, buf, 4) != 4)
return 0;
- *p = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
+ work = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16) + ((i_packed_t)buf[3] << 24);
+ if (shrieking)
+ *p = (work ^ SIGNBIT32) - SIGNBIT32;
+ else
+ *p = work;
break;
case 'C':
case '3': /* extension - 24-bit number */
if (ig->readcb(ig, buf, 3) != 3)
return 0;
- *p = buf[0] + (buf[1] << 8) + (buf[2] << 16);
+ *p = buf[0] + (buf[1] << 8) + ((i_packed_t)buf[2] << 16);
break;
default:
- i_fatal(1, "Unknown read_packed format code 0x%02x", *format);
+ i_fatal(1, "Unknown read_packed format code 0x%02x", code);
}
- ++format;
}
return 1;
}
va_start(ap, format);
while (*format) {
- i = va_arg(ap, unsigned int);
+ i = va_arg(ap, i_upacked_t);
switch (*format) {
case 'v':
int colors_used = 0;
int offset = FILEHEAD_SIZE + INFOHEAD_SIZE;
+ if (im->xsize > SIGNMAX32 || im->ysize > SIGNMAX32) {
+ i_push_error(0, "image too large to write to BMP");
+ return 0;
+ }
+
got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
offset += 4 * colors_used;
}
- if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M', data_size+offset,
- 0, 0, offset, INFOHEAD_SIZE, im->xsize, im->ysize, 1,
- bit_count, BI_RGB, data_size, (int)(xres+0.5), (int)(yres+0.5),
- colors_used, colors_used)){
+ if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M',
+ (i_upacked_t)(data_size+offset),
+ (i_upacked_t)0, (i_upacked_t)0, (i_upacked_t)offset,
+ (i_upacked_t)INFOHEAD_SIZE, (i_upacked_t)im->xsize,
+ (i_upacked_t)im->ysize, (i_upacked_t)1,
+ (i_upacked_t)bit_count, (i_upacked_t)BI_RGB,
+ (i_upacked_t)data_size,
+ (i_upacked_t)(xres+0.5), (i_upacked_t)(yres+0.5),
+ (i_upacked_t)colors_used, (i_upacked_t)colors_used)){
i_push_error(0, "cannot write bmp header");
return 0;
}
for (i = 0; i < colors_used; ++i) {
i_getcolors(im, i, &c, 1);
if (im->channels >= 3) {
- if (!write_packed(ig, "CCCC", c.channel[2], c.channel[1],
- c.channel[0], 0)) {
+ if (!write_packed(ig, "CCCC", (i_upacked_t)(c.channel[2]),
+ (i_upacked_t)(c.channel[1]),
+ (i_upacked_t)(c.channel[0]), (i_upacked_t)0)) {
i_push_error(0, "cannot write palette entry");
return 0;
}
}
else {
- if (!write_packed(ig, "CCCC", c.channel[0], c.channel[0],
- c.channel[0], 0)) {
+ i_upacked_t v = c.channel[0];
+ if (!write_packed(ig, "CCCC", v, v, v, 0)) {
i_push_error(0, "cannot write palette entry");
return 0;
}
static int
read_bmp_pal(io_glue *ig, i_img *im, int count) {
int i;
- int r, g, b, x;
+ i_packed_t r, g, b, x;
i_color c;
for (i = 0; i < count; ++i) {
compression_name = "BI_BITFIELDS";
for (i = 0; i < 3; ++i) {
- if (!read_packed(ig, "V", masks.masks+i)) {
+ i_packed_t rmask;
+ if (!read_packed(ig, "V", &rmask)) {
i_push_error(0, "reading pixel masks");
return 0;
}
+ masks.masks[i] = rmask;
/* work out a shift for the mask */
pos = 0;
bit = masks.masks[i] & -masks.masks[i];
while (y != lasty) {
p = line;
for (x = 0; x < xsize; ++x) {
- unsigned pixel;
+ i_packed_t pixel;
if (!read_packed(ig, unpack_code, &pixel)) {
myfree(line);
if (allow_incomplete) {
int
i_compose_mask(i_img *out, i_img *src, i_img *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) {
i_render r;
- int dy;
+ i_img_dim dy;
i_fill_combine_f combinef_8;
i_fill_combinef_f combinef_double;
int channel_zero = 0;
- mm_log((1, "i_compose_mask(out %p, src %p, mask %p, out(%d, %d), src(%d, %d),"
- " mask(%d,%d), size(%d,%d), combine %d opacity %f\n", out, src,
- mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width,
- height, combine, opacity));
+ mm_log((1, "i_compose_mask(out %p, src %p, mask %p, out(" i_DFp "), "
+ "src(" i_DFp "), mask(" i_DFp "), size(" i_DFp "),"
+ " combine %d opacity %f\n", out, src,
+ mask, i_DFcp(out_left, out_top), i_DFcp(src_left, src_top),
+ i_DFcp(mask_left, mask_top), i_DFcp(width, height),
+ combine, opacity));
i_clear_error();
if (out_left >= out->xsize
return 0;
}
- mm_log((1, "after adjustments: (out(%d, %d), src(%d, %d),"
- " mask(%d,%d), size(%d,%d)\n",
- out_left, out_top, src_left, src_top, mask_left, mask_top, width,
- height));
+ mm_log((1, "after adjustments: (out(" i_DFp "), src(" i_DFp "),"
+ " mask(" i_DFp "), size(" i_DFp ")\n",
+ i_DFcp(out_left, out_top), i_DFcp(src_left, src_top),
+ i_DFcp(mask_left, mask_top), i_DFcp(width, height)));
i_get_combine(combine, &combinef_8, &combinef_double);
IM_GSAMP(mask, mask_left, mask_left + width, mask_top + dy,
mask_line, &channel_zero, 1);
if (opacity < 1.0) {
- int i;
+ i_img_dim i;
IM_SAMPLE_T *maskp = mask_line;
for (i = 0; i < width; ++i) {
*maskp = IM_ROUND(*maskp * opacity);
int
i_compose(i_img *out, i_img *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) {
i_render r;
- int dy;
+ i_img_dim dy;
i_fill_combine_f combinef_8;
i_fill_combinef_f combinef_double;
- mm_log((1, "i_compose(out %p, src %p, out(%d, %d), src(%d, %d), size(%d,%d),"
- " combine %d opacity %f\n", out, src, out_left, out_top,
- src_left, src_top, width, height, combine, opacity));
+ mm_log((1, "i_compose(out %p, src %p, out(" i_DFp "), src(" i_DFp "), "
+ "size(" i_DFp "), combine %d opacity %f\n", out, src,
+ i_DFcp(out_left, out_top), i_DFcp(src_left, src_top),
+ i_DFcp(width, height), combine, opacity));
i_clear_error();
if (out_left >= out->xsize
int adapt_channels = out->channels;
if (opacity != 1.0) {
- int i;
+ i_img_dim i;
IM_SAMPLE_T mask_value = IM_ROUND(opacity * IM_SAMPLE_MAX);
mask_line = mymalloc(sizeof(IM_SAMPLE_T) * width);
end effects are acounted for by increasing
scaling the result with the sum of used coefficients
- coeff: (float array) coefficients for filter
+ coeff: (double array) coefficients for filter
len: length of filter.. number of coefficients
note that this has to be an odd number
(since the filter is even);
int
i_conv(i_img *im, const double *coeff,int len) {
- int xo, yo; /* output pixel co-ordinate */
+ i_img_dim xo, yo; /* output pixel co-ordinate */
int c, ch, center;
double pc;
double res[MAXCHANNELS];
for(ch = 0;ch < im->channels; ch++)
res[ch] = 0;
for(c = 0;c < len; c++) {
- int xi = xo + c - center;
+ i_img_dim xi = xo + c - center;
if (xi < 0)
xi = 0;
else if (xi >= im->xsize)
for(ch = 0; ch < im->channels; ch++)
res[ch] = 0;
for(c = 0; c < len; c++) {
- int yi = yo + c - center;
+ i_img_dim yi = yo + c - center;
if (yi < 0)
yi = 0;
else if (yi >= im->ysize)
i_img *
i_convert(i_img *src, const double *coeff, int outchan, int inchan) {
double work[MAXCHANNELS];
- int x, y;
+ i_img_dim x, y;
int i, j;
int ilimit;
i_img *im = NULL;
- mm_log((1,"i_convert(src %p, coeff %p,outchan %d, inchan %d)\n",im,src, coeff,outchan, inchan));
+ mm_log((1,"i_convert(im %p, src %p, coeff %p,outchan %d, inchan %d)\n",
+ im, src, coeff, outchan, inchan));
i_clear_error();
*/
struct i_bitmap*
-btm_new(int xsize,int ysize) {
- int i;
- int bytes;
+btm_new(i_img_dim xsize,i_img_dim ysize) {
+ i_img_dim i;
+ size_t bytes;
struct i_bitmap *btm;
btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
bytes = (xsize*ysize+8)/8;
if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
- fprintf(stderr, "Integer overflow allocating bitmap %d x %d", xsize, ysize);
+ fprintf(stderr, "Integer overflow allocating bitmap (" i_DFp ")",
+ i_DFcp(xsize, ysize));
exit(3);
}
btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
int
-btm_test(struct i_bitmap *btm,int x,int y) {
- int btno;
+btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
+ i_img_dim btno;
if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) return 0;
btno=btm->xsize*y+x;
return (1<<(btno%8))&(btm->data[btno/8]);
}
void
-btm_set(struct i_bitmap *btm,int x,int y) {
- int btno;
+btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y) {
+ i_img_dim btno;
if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort();
btno=btm->xsize*y+x;
btm->data[btno/8]|=1<<(btno%8);
Bucketed linked list - stack type
*/
-struct llink *
-llink_new(struct llink* p,int size) {
- struct llink *l;
- l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
- l->n = NULL;
- l->p = p;
- l->fill = 0;
- l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
- return l;
-}
+static struct llink *
+llink_new(struct llink* p,size_t size);
+static int
+llist_llink_push(struct llist *lst, struct llink *lnk,const void *data);
+static void
+llink_destroy(struct llink* l);
-/* free's the data pointer, itself, and sets the previous' next pointer to null */
+/*
+=item llist_new()
+=synopsis struct llist *l = llist_new(100, sizeof(foo);
-void
-llink_destroy(struct llink* l) {
- if (l->p != NULL) { l->p->n=NULL; }
- myfree(l->data);
- myfree(l);
-}
+Create a new stack structure. Implemented as a linked list of pools.
+Parameters:
-/* if it returns true there wasn't room for the
- item on the link */
+=over
-int
-llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
- int multip;
- multip = lst->multip;
+=item *
- /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
- fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
- if (lnk->fill == lst->multip) return 1;
- /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
- memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
-
- /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
- lnk->fill++;
- lst->count++;
- return 0;
-}
+multip - number of entries in each pool
+
+=item *
+
+ssize - size of the objects being pushed/popped
+
+=back
+
+=cut
+*/
struct llist *
-llist_new(int multip, int ssize) {
+llist_new(int multip, size_t ssize) {
struct llist *l;
l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
l->h = NULL;
return l;
}
+/*
+=item llist_push()
+=synopsis llist_push(l, &foo);
+
+Push an item on the stack.
+
+=cut
+*/
+
void
-llist_push(struct llist *l,void *data) {
- int ssize = l->ssize;
+llist_push(struct llist *l,const void *data) {
+ size_t ssize = l->ssize;
int multip = l->multip;
/* fprintf(stderr,"llist_push: data=0x%08X\n",data);
}
}
-/* returns 0 if the list is empty */
+/*
+=item llist_pop()
+
+Pop an item off the list, storing it at C<data> which must have enough room for an object of the size supplied to llist_new().
+
+returns 0 if the list is empty
+
+=cut
+*/
int
llist_pop(struct llist *l,void *data) {
}
}
+/*
+=item llist_destroy()
+
+Destroy a linked-list based stack.
+
+=cut
+*/
+
void
llist_destroy(struct llist *l) {
struct llink *t,*lnk = l->h;
myfree(l);
}
+/* Links */
+
+static struct llink *
+llink_new(struct llink* p,size_t size) {
+ struct llink *l;
+ l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
+ l->n = NULL;
+ l->p = p;
+ l->fill = 0;
+ l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
+ return l;
+}
+
+/* free's the data pointer, itself, and sets the previous' next pointer to null */
+
+static void
+llink_destroy(struct llink* l) {
+ if (l->p != NULL) { l->p->n=NULL; }
+ myfree(l->data);
+ myfree(l);
+}
+/* if it returns true there wasn't room for the
+ item on the link */
+static int
+llist_llink_push(struct llist *lst, struct llink *lnk, const void *data) {
+ int multip;
+ multip = lst->multip;
+ /* fprintf(stderr,"llist_llink_push: data=0x%08X -> 0x%08X\n",data,*(int*)data);
+ fprintf(stderr,"ssize = %d, multip = %d, fill = %d\n",lst->ssize,lst->multip,lnk->fill); */
+ if (lnk->fill == lst->multip) return 1;
+ /* memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize); */
+ memcpy((char*)(lnk->data)+lnk->fill*lst->ssize,data,lst->ssize);
+
+ /* printf("data=%X res=%X\n",*(int*)data,*(int*)(lnk->data));*/
+ lnk->fill++;
+ lst->count++;
+ return 0;
+}
/*
Oct-tree implementation
}
+i_img_dim
+i_abs(i_img_dim x) {
+ return x < 0 ? -x : x;
+}
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);
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);
static void
cfill_from_btm(i_img *im, i_fill_t *fill, struct i_bitmap *btm,
- int bxmin, int bxmax, int bymin, int bymax);
+ i_img_dim bxmin, i_img_dim bxmax, i_img_dim bymin, i_img_dim bymax);
void
-i_mmarray_cr(i_mmarray *ar,int l) {
- int i;
- int alloc_size;
+i_mmarray_cr(i_mmarray *ar,i_img_dim l) {
+ i_img_dim i;
+ size_t alloc_size;
ar->lines=l;
alloc_size = sizeof(minmax) * l;
}
void
-i_mmarray_add(i_mmarray *ar,int x,int y) {
+i_mmarray_add(i_mmarray *ar,i_img_dim x,i_img_dim y) {
if (y>-1 && y<ar->lines)
{
if (x<ar->data[y].min) ar->data[y].min=x;
}
int
-i_mmarray_gmin(i_mmarray *ar,int y) {
+i_mmarray_gmin(i_mmarray *ar,i_img_dim y) {
if (y>-1 && y<ar->lines) return ar->data[y].min;
else return -1;
}
int
-i_mmarray_getm(i_mmarray *ar,int y) {
+i_mmarray_getm(i_mmarray *ar,i_img_dim y) {
if (y>-1 && y<ar->lines) return ar->data[y].max;
else return MAXINT;
}
+#if 0
+/* unused? */
void
i_mmarray_render(i_img *im,i_mmarray *ar,i_color *val) {
- int i,x;
+ i_img_dim i,x;
for(i=0;i<ar->lines;i++) if (ar->data[i].max!=-1) for(x=ar->data[i].min;x<ar->data[i].max;x++) i_ppix(im,x,i,val);
}
+#endif
static
void
-i_arcdraw(int x1, int y1, int x2, int y2, i_mmarray *ar) {
+i_arcdraw(i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_mmarray *ar) {
double alpha;
double dsec;
- int temp;
+ i_img_dim temp;
alpha=(double)(y2-y1)/(double)(x2-x1);
if (fabs(alpha) <= 1)
{
dsec=y1;
while(x1<=x2)
{
- i_mmarray_add(ar,x1,(int)(dsec+0.5));
+ i_mmarray_add(ar,x1,(i_img_dim)(dsec+0.5));
dsec+=alpha;
x1++;
}
dsec=x1;
while(y1<=y2)
{
- i_mmarray_add(ar,(int)(dsec+0.5),y1);
+ i_mmarray_add(ar,(i_img_dim)(dsec+0.5),y1);
dsec+=alpha;
y1++;
}
void
i_mmarray_info(i_mmarray *ar) {
- int i;
+ i_img_dim i;
for(i=0;i<ar->lines;i++)
- if (ar->data[i].max!=-1) printf("line %d: min=%d, max=%d.\n",i,ar->data[i].min,ar->data[i].max);
+ if (ar->data[i].max!=-1)
+ printf("line %"i_DF ": min=%" i_DF ", max=%" i_DF ".\n",
+ i_DFc(i), i_DFc(ar->data[i].min), i_DFc(ar->data[i].max));
}
static void
-i_arc_minmax(i_int_hlines *hlines,int x,int y,float rad,float d1,float d2) {
+i_arc_minmax(i_int_hlines *hlines,i_img_dim x,i_img_dim y, double rad,float d1,float d2) {
i_mmarray dot;
- float f,fx,fy;
- int x1,y1;
-
- /*mm_log((1,"i_arc(im* 0x%x,x %d,y %d,rad %.2f,d1 %.2f,d2 %.2f,val 0x%x)\n",im,x,y,rad,d1,d2,val));*/
+ double f,fx,fy;
+ i_img_dim x1,y1;
i_mmarray_cr(&dot, hlines->limit_y);
- x1=(int)(x+0.5+rad*cos(d1*PI/180.0));
- y1=(int)(y+0.5+rad*sin(d1*PI/180.0));
+ x1=(i_img_dim)(x+0.5+rad*cos(d1*PI/180.0));
+ y1=(i_img_dim)(y+0.5+rad*sin(d1*PI/180.0));
fx=(float)x1; fy=(float)y1;
/* printf("x1: %d.\ny1: %d.\n",x1,y1); */
i_arcdraw(x, y, x1, y1, &dot);
- x1=(int)(x+0.5+rad*cos(d2*PI/180.0));
- y1=(int)(y+0.5+rad*sin(d2*PI/180.0));
+ x1=(i_img_dim)(x+0.5+rad*cos(d2*PI/180.0));
+ y1=(i_img_dim)(y+0.5+rad*sin(d2*PI/180.0));
- for(f=d1;f<=d2;f+=0.01) i_mmarray_add(&dot,(int)(x+0.5+rad*cos(f*PI/180.0)),(int)(y+0.5+rad*sin(f*PI/180.0)));
+ for(f=d1;f<=d2;f+=0.01)
+ i_mmarray_add(&dot,(i_img_dim)(x+0.5+rad*cos(f*PI/180.0)),(i_img_dim)(y+0.5+rad*sin(f*PI/180.0)));
/* printf("x1: %d.\ny1: %d.\n",x1,y1); */
i_arcdraw(x, y, x1, y1, &dot);
/* render the minmax values onto the hlines */
for (y = 0; y < dot.lines; y++) {
if (dot.data[y].max!=-1) {
- int minx, width;
+ i_img_dim minx, width;
minx = dot.data[y].min;
width = dot.data[y].max - dot.data[y].min + 1;
i_int_hlines_add(hlines, y, minx, width);
}
static void
-i_arc_hlines(i_int_hlines *hlines,int x,int y,float rad,float d1,float d2) {
+i_arc_hlines(i_int_hlines *hlines,i_img_dim x,i_img_dim y,double rad,float d1,float d2) {
if (d1 <= d2) {
i_arc_minmax(hlines, x, y, rad, d1, d2);
}
*/
void
-i_arc(i_img *im,int x,int y,float rad,float d1,float d2,const i_color *val) {
+i_arc(i_img *im, i_img_dim x, i_img_dim y,double rad,double d1,double d2,const i_color *val) {
i_int_hlines hlines;
i_int_init_hlines_img(&hlines, im);
#define MAX_CIRCLE_STEPS 360
void
-i_arc_cfill(i_img *im,int x,int y,float rad,float d1,float d2,i_fill_t *fill) {
+i_arc_cfill(i_img *im, i_img_dim x, i_img_dim y,double rad,double d1,double d2,i_fill_t *fill) {
i_int_hlines hlines;
i_int_init_hlines_img(&hlines, im);
double x, double y, double rad, double d1, double d2) {
double d1_rad, d2_rad;
double circum;
- int steps, point_count;
+ i_img_dim steps, point_count;
double angle_inc;
/* normalize the angles */
/* Temporary AA HACK */
-typedef int frac;
-static frac float_to_frac(float x) { return (frac)(0.5+x*16.0); }
+typedef i_img_dim frac;
+static frac float_to_frac(double x) { return (frac)(0.5+x*16.0); }
static
void
-polar_to_plane(float cx, float cy, float angle, float radius, frac *x, frac *y) {
+polar_to_plane(double cx, double cy, float angle, double radius, frac *x, frac *y) {
*x = float_to_frac(cx+radius*cos(angle));
*y = float_to_frac(cy+radius*sin(angle));
}
static
void
-make_minmax_list(i_mmarray *dot, float x, float y, float radius) {
+make_minmax_list(i_mmarray *dot, double x, double y, double radius) {
float angle = 0.0;
float astep = radius>0.1 ? .5/radius : 10;
frac cx, cy, lx, ly, sx, sy;
static
int
-i_pixel_coverage(i_mmarray *dot, int x, int y) {
+i_pixel_coverage(i_mmarray *dot, i_img_dim x, i_img_dim y) {
frac minx = x*16;
frac maxx = minx+15;
frac cy;
=cut
*/
void
-i_circle_aa(i_img *im, float x, float y, float rad, const i_color *val) {
+i_circle_aa(i_img *im, double x, double y, double rad, const i_color *val) {
i_mmarray dot;
i_color temp;
- int ly;
+ i_img_dim ly;
- mm_log((1, "i_circle_aa(im %p, x %d, y %d, rad %.2f, val %p)\n", im, x, y, rad, val));
+ mm_log((1, "i_circle_aa(im %p, centre(" i_DFp "), rad %.2f, val %p)\n",
+ im, i_DFcp(x, y), rad, val));
i_mmarray_cr(&dot,16*im->ysize);
make_minmax_list(&dot, x, y, rad);
arc_seg(double angle, int scale) {
i_img_dim seg = (angle + 45) / 90;
double remains = angle - seg * 90; /* should be in the range [-45,45] */
- int sign = remains < 0 ? -1 : remains ? 1 : 0;
while (seg > 4)
seg -= 4;
int
i_arc_out(i_img *im, i_img_dim xc, i_img_dim yc, i_img_dim r,
- float d1, float d2, const i_color *col) {
+ double d1, double d2, const i_color *col) {
i_img_dim x, y;
i_img_dim dx, dy;
int error;
i_img_dim sin_th;
i_img_dim seg_d1, seg_d2;
int seg_num;
- double inv_r;
i_img_dim scale = r + 1;
i_img_dim seg1 = scale * 2;
i_img_dim seg2 = scale * 4;
static double
cover(i_img_dim r, i_img_dim j) {
- float rjsqrt = sqrt(r*r - j*j);
+ double rjsqrt = sqrt(r*r - j*j);
return ceil(rjsqrt) - rjsqrt;
}
while (i > j+1) {
double d;
int cv, inv_cv;
- i_color p;
- int ch;
j++;
d = cover(r, j);
cv = (int)(d * 255 + 0.5);
*/
int
-i_arc_out_aa(i_img *im, i_img_dim xc, i_img_dim yc, i_img_dim r, float d1, float d2, const i_color *col) {
+i_arc_out_aa(i_img *im, i_img_dim xc, i_img_dim yc, i_img_dim r, double d1, double d2, const i_color *col) {
i_img_dim i, j;
double t;
i_color workc = *col;
while (i > j+1) {
int cv, inv_cv;
- i_color p;
- int ch;
double d;
j++;
d = cover(r, j);
*/
void
-i_box(i_img *im,int x1,int y1,int x2,int y2,const i_color *val) {
- int x,y;
- mm_log((1,"i_box(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,val 0x%x)\n",im,x1,y1,x2,y2,val));
+i_box(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val) {
+ i_img_dim x,y;
+ mm_log((1,"i_box(im* %p, p1(" i_DFp "), p2(" i_DFp "),val %p)\n",
+ im, i_DFcp(x1,y1), i_DFcp(x2,y2), val));
for(x=x1;x<x2+1;x++) {
i_ppix(im,x,y1,val);
i_ppix(im,x,y2,val);
*/
void
-i_box_filled(i_img *im,int x1,int y1,int x2,int y2, const i_color *val) {
+i_box_filled(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2, const i_color *val) {
i_img_dim x, y, width;
i_palidx index;
- mm_log((1,"i_box_filled(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,val 0x%x)\n",im,x1,y1,x2,y2,val));
+ mm_log((1,"i_box_filled(im* %p, p1(" i_DFp "), p2(" i_DFp "),val %p)\n",
+ im, i_DFcp(x1, y1), i_DFcp(x2,y2) ,val));
if (x1 > x2 || y1 > y2
|| x2 < 0 || y2 < 0
*/
int
-i_box_filledf(i_img *im,int x1,int y1,int x2,int y2, const i_fcolor *val) {
+i_box_filledf(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2, const i_fcolor *val) {
i_img_dim x, y, width;
- i_palidx index;
- mm_log((1,"i_box_filledf(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,val 0x%x)\n",im,x1,y1,x2,y2,val));
+ mm_log((1,"i_box_filledf(im* %p, p1(" i_DFp "), p2(" i_DFp "),val %p)\n",
+ im, i_DFcp(x1, y1), i_DFcp(x2, y2), val));
if (x1 > x2 || y1 > y2
|| x2 < 0 || y2 < 0
*/
void
-i_box_cfill(i_img *im,int x1,int y1,int x2,int y2,i_fill_t *fill) {
+i_box_cfill(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_fill_t *fill) {
i_render r;
- mm_log((1,"i_box_cfill(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,fill 0x%x)\n",im,x1,y1,x2,y2,fill));
+
+ mm_log((1,"i_box_cfill(im* %p, p1(" i_DFp "), p2(" i_DFp "), fill %p)\n",
+ im, i_DFcp(x1, y1), i_DFcp(x2,y2), fill));
++x2;
if (x1 < 0)
*/
void
-i_line(i_img *im, int x1, int y1, int x2, int y2, const i_color *val, int endp) {
- int x, y;
- int dx, dy;
- int p;
+i_line(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val, int endp) {
+ i_img_dim x, y;
+ i_img_dim dx, dy;
+ i_img_dim p;
dx = x2 - x1;
dy = y2 - y1;
/* choose variable to iterate on */
- if (abs(dx)>abs(dy)) {
- int dx2, dy2, cpy;
+ if (i_abs(dx) > i_abs(dy)) {
+ i_img_dim dx2, dy2, cpy;
/* sort by x */
if (x1 > x2) {
- int t;
+ i_img_dim t;
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
}
- dx = abs(dx);
+ dx = i_abs(dx);
dx2 = dx*2;
dy = y2 - y1;
i_ppix(im, x+1, y, val);
}
} else {
- int dy2, dx2, cpx;
+ i_img_dim dy2, dx2, cpx;
/* sort bx y */
if (y1 > y2) {
- int t;
+ i_img_dim t;
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
}
- dy = abs(dy);
+ dy = i_abs(dy);
dx = x2 - x1;
dy2 = dy*2;
void
-i_line_dda(i_img *im, int x1, int y1, int x2, int y2, i_color *val) {
+i_line_dda(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_color *val) {
- float dy;
- int x;
+ double dy;
+ i_img_dim x;
for(x=x1; x<=x2; x++) {
- dy = y1+ (x-x1)/(float)(x2-x1)*(y2-y1);
- i_ppix(im, x, (int)(dy+0.5), val);
+ dy = y1+ (x-x1)/(double)(x2-x1)*(y2-y1);
+ i_ppix(im, x, (i_img_dim)(dy+0.5), val);
}
}
*/
void
-i_line_aa(i_img *im, int x1, int y1, int x2, int y2, const i_color *val, int endp) {
- int x, y;
- int dx, dy;
- int p;
+i_line_aa(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val, int endp) {
+ i_img_dim x, y;
+ i_img_dim dx, dy;
+ i_img_dim p;
dx = x2 - x1;
dy = y2 - y1;
/* choose variable to iterate on */
- if (abs(dx)>abs(dy)) {
- int dx2, dy2, cpy;
+ if (i_abs(dx) > i_abs(dy)) {
+ i_img_dim dx2, dy2, cpy;
/* sort by x */
if (x1 > x2) {
- int t;
+ i_img_dim t;
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
}
- dx = abs(dx);
+ dx = i_abs(dx);
dx2 = dx*2;
dy = y2 - y1;
for(x=x1; x<x2-1; x++) {
int ch;
i_color tval;
- float t = (dy) ? -(float)(p)/(float)(dx2) : 1;
- float t1, t2;
+ double t = (dy) ? -(float)(p)/(float)(dx2) : 1;
+ double t1, t2;
if (t<0) t = 0;
t1 = 1-t;
}
}
} else {
- int dy2, dx2, cpx;
+ i_img_dim dy2, dx2, cpx;
/* sort bx y */
if (y1 > y2) {
- int t;
+ i_img_dim t;
t = x1; x1 = x2; x2 = t;
t = y1; y1 = y2; y2 = t;
}
- dy = abs(dy);
+ dy = i_abs(dy);
dx = x2 - x1;
dy2 = dy*2;
for(y=y1; y<y2-1; y++) {
int ch;
i_color tval;
- float t = (dx) ? -(float)(p)/(float)(dy2) : 1;
- float t1, t2;
+ double t = (dx) ? -(double)(p)/(double)(dy2) : 1;
+ double t1, t2;
if (t<0) t = 0;
t1 = 1-t;
i_gpix(im,x,y+1,&tval);
for(ch=0;ch<im->channels;ch++)
- tval.channel[ch]=(unsigned char)(t1*(float)tval.channel[ch]+t2*(float)val->channel[ch]);
+ tval.channel[ch]=(unsigned char)(t1*(double)tval.channel[ch]+t2*(double)val->channel[ch]);
i_ppix(im,x,y+1,&tval);
i_gpix(im,x+cpx,y+1,&tval);
for(ch=0;ch<im->channels;ch++)
- tval.channel[ch]=(unsigned char)(t2*(float)tval.channel[ch]+t1*(float)val->channel[ch]);
+ tval.channel[ch]=(unsigned char)(t2*(double)tval.channel[ch]+t1*(double)val->channel[ch]);
i_ppix(im,x+cpx,y+1,&tval);
if (p<0) {
static double
-perm(int n,int k) {
+perm(i_img_dim n,i_img_dim k) {
double r;
- int i;
+ i_img_dim i;
r=1;
for(i=k+1;i<=n;i++) r*=i;
for(i=1;i<=(n-k);i++) r/=i;
double *bzcoef;
double t,cx,cy;
int k,i;
- int lx = 0,ly = 0;
+ i_img_dim lx = 0,ly = 0;
int n=l-1;
double itr,ccoef;
}
/* printf("%f -> (%d,%d)\n",t,(int)(0.5+cx),(int)(0.5+cy)); */
if (i++) {
- i_line_aa(im,lx,ly,(int)(0.5+cx),(int)(0.5+cy),val, 1);
+ i_line_aa(im,lx,ly,(i_img_dim)(0.5+cx),(i_img_dim)(0.5+cy),val, 1);
}
- /* i_ppix(im,(int)(0.5+cx),(int)(0.5+cy),val); */
- lx=(int)(0.5+cx);
- ly=(int)(0.5+cy);
+ /* i_ppix(im,(i_img_dim)(0.5+cx),(i_img_dim)(0.5+cy),val); */
+ lx=(i_img_dim)(0.5+cx);
+ ly=(i_img_dim)(0.5+cy);
}
ICL_info(val);
myfree(bzcoef);
/*
struct stc {
- int mylx,myrx;
- int dadlx,dadrx;
- int myy;
+ i_img_dim mylx,myrx;
+ i_img_dim dadlx,dadrx;
+ i_img_dim myy;
int mydirection;
};
struct stack_element {
- int myLx,myRx;
- int dadLx,dadRx;
- int myY;
+ i_img_dim myLx,myRx;
+ i_img_dim dadLx,dadRx;
+ i_img_dim myY;
int myDirection;
};
static
struct stack_element*
-crdata(int left,int right,int dadl,int dadr,int y, int dir) {
+crdata(i_img_dim left,i_img_dim right,i_img_dim dadl,i_img_dim dadr,i_img_dim y, int dir) {
struct stack_element *ste;
ste = mymalloc(sizeof(struct stack_element)); /* checked 5jul05 tonyc */
ste->myLx = left;
}
static int
-i_lspan(i_img *im, int seedx, int seedy, i_color const *val, ff_cmpfunc cmpfunc) {
+i_lspan(i_img *im, i_img_dim seedx, i_img_dim seedy, i_color const *val, ff_cmpfunc cmpfunc) {
i_color cval;
while(1) {
if (seedx-1 < 0) break;
}
static int
-i_rspan(i_img *im, int seedx, int seedy, i_color const *val, ff_cmpfunc cmpfunc) {
+i_rspan(i_img *im, i_img_dim seedx, i_img_dim seedy, i_color const *val, ff_cmpfunc cmpfunc) {
i_color cval;
while(1) {
if (seedx+1 > im->xsize-1) break;
} while (0)
#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) do { \
- int pushrx = rx+1; \
- int pushlx = lx-1; \
+ i_img_dim pushrx = rx+1; \
+ i_img_dim pushlx = lx-1; \
ST_PUSH(lx,rx,pushlx,pushrx,y+dir,dir); \
if (rx > dadRx) \
ST_PUSH(dadRx+1,rx,pushlx,pushrx,y-dir,-dir); \
/* The function that does all the real work */
static struct i_bitmap *
-i_flood_fill_low(i_img *im,int seedx,int seedy,
- int *bxminp, int *bxmaxp, int *byminp, int *bymaxp,
+i_flood_fill_low(i_img *im,i_img_dim seedx,i_img_dim seedy,
+ i_img_dim *bxminp, i_img_dim *bxmaxp, i_img_dim *byminp, i_img_dim *bymaxp,
i_color const *seed, ff_cmpfunc cmpfunc) {
- int ltx, rtx;
- int tx = 0;
+ i_img_dim ltx, rtx;
+ i_img_dim tx = 0;
- int bxmin = seedx;
- int bxmax = seedx;
- int bymin = seedy;
- int bymax = seedy;
+ i_img_dim bxmin = seedx;
+ i_img_dim bxmax = seedx;
+ i_img_dim bymin = seedy;
+ i_img_dim bymax = seedy;
struct llist *st;
struct i_bitmap *btm;
- int channels,xsize,ysize;
+ int channels;
+ i_img_dim xsize,ysize;
i_color cval;
channels = im->channels;
while(st->count) {
/* Stack variables */
- int lx,rx;
- int dadLx,dadRx;
- int y;
+ i_img_dim lx,rx;
+ i_img_dim dadLx,dadRx;
+ i_img_dim y;
int direction;
- int x;
+ i_img_dim x;
int wasIn=0;
ST_POP(); /* sets lx, rx, dadLx, dadRx, y, direction */
*/
undef_int
-i_flood_fill(i_img *im, int seedx, int seedy, const i_color *dcol) {
- int bxmin, bxmax, bymin, bymax;
+i_flood_fill(i_img *im, i_img_dim seedx, i_img_dim seedy, const i_color *dcol) {
+ i_img_dim bxmin, bxmax, bymin, bymax;
struct i_bitmap *btm;
- int x, y;
+ i_img_dim x, y;
i_color val;
i_clear_error();
*/
undef_int
-i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill) {
- int bxmin, bxmax, bymin, bymax;
+i_flood_cfill(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill) {
+ i_img_dim bxmin, bxmax, bymin, bymax;
struct i_bitmap *btm;
i_color val;
*/
undef_int
-i_flood_fill_border(i_img *im, int seedx, int seedy, const i_color *dcol,
+i_flood_fill_border(i_img *im, i_img_dim seedx, i_img_dim seedy, const i_color *dcol,
const i_color *border) {
- int bxmin, bxmax, bymin, bymax;
+ i_img_dim bxmin, bxmax, bymin, bymax;
struct i_bitmap *btm;
- int x, y;
+ i_img_dim x, y;
i_clear_error();
if (seedx < 0 || seedx >= im->xsize ||
*/
undef_int
-i_flood_cfill_border(i_img *im, int seedx, int seedy, i_fill_t *fill,
+i_flood_cfill_border(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill,
const i_color *border) {
- int bxmin, bxmax, bymin, bymax;
+ i_img_dim bxmin, bxmax, bymin, bymax;
struct i_bitmap *btm;
i_clear_error();
static void
cfill_from_btm(i_img *im, i_fill_t *fill, struct i_bitmap *btm,
- int bxmin, int bxmax, int bymin, int bymax) {
- int x, y;
- int start;
+ i_img_dim bxmin, i_img_dim bxmax, i_img_dim bymin, i_img_dim bymax) {
+ i_img_dim x, y;
+ i_img_dim start;
i_render r;
#include "imager.h"
typedef struct {
- int min,max;
+ i_img_dim min,max;
} minmax;
typedef struct {
minmax *data;
- int lines;
+ i_img_dim lines;
} i_mmarray;
/* FIXME: Merge this into datatypes.{c,h} */
-void i_mmarray_cr(i_mmarray *ar,int l);
+void i_mmarray_cr(i_mmarray *ar,i_img_dim l);
void i_mmarray_dst(i_mmarray *ar);
-void i_mmarray_add(i_mmarray *ar,int x,int y);
-int i_mmarray_gmin(i_mmarray *ar,int y);
-int i_mmarray_getm(i_mmarray *ar,int y);
-void i_mmarray_render(i_img *im,i_mmarray *ar,i_color *val);
+void i_mmarray_add(i_mmarray *ar,i_img_dim x,i_img_dim y);
+int i_mmarray_gmin(i_mmarray *ar,i_img_dim y);
+int i_mmarray_getm(i_mmarray *ar,i_img_dim y);
void i_mmarray_info(i_mmarray *ar);
-
+#if 0
+void i_mmarray_render(i_img *im,i_mmarray *ar,i_color *val);
+#endif
void
DSO_call(DSO_handle *handle,int func_index,HV* hv) {
- mm_log((1,"DSO_call(handle 0x%X, func_index %d, hv 0x%X)\n",handle,func_index,hv));
+ mm_log((1,"DSO_call(handle %p, func_index %d, hv %p)\n",
+ handle, func_index, hv));
(handle->function_list[func_index].iptr)((void*)hv);
}
void (*f)(void *s,void *u); /* these will just have to be void for now */
- mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
+ mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",file,file,evalstring) );
*evalstring = NULL;
if ((d_handle = LoadLibrary(file)) == NULL) {
}
strcpy(dso_handle->filename,file);
- mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
+ mm_log( (1,"DSO_open <- %p\n",dso_handle) );
return (void*)dso_handle;
}
*evalstring=NULL;
- mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
+ mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",
+ file, file, evalstring) );
if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
}
strcpy(dso_handle->filename,file);
- mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
+ mm_log( (1,"DSO_open <- %p\n",dso_handle) );
return (void*)dso_handle;
}
undef_int
DSO_close(void *ptr) {
DSO_handle *handle;
- mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
+ mm_log((1,"DSO_close(ptr %p)\n",ptr));
handle=(DSO_handle*) ptr;
return !dlclose(handle->handle);
}
html_art(void *INP) {
i_img *im;
i_color rcolor;
- int x,y;
+ i_img_dim x,y;
FILE *fp;
char *fname;
if ( !getSTR("fname",&fname) ) { fprintf(stderr,"Error: filename is missing\n"); return; }
if ( !getOBJ("image","Imager::ImgRaw",&im) ) { fprintf(stderr,"Error: image is missing\n"); return; }
- printf("parameters: (im 0x%p,fname %s)\n",im,fname);
+ printf("parameters: (im %p,fname %s)\n",im,fname);
- printf("image info:\n size (%d,%d)\n channels (%d)\n",
- im->xsize,im->ysize,im->channels);
+ printf("image info:\n size ("i_DFp ")\n channels (%d)\n",
+ i_DFcp(im->xsize, im->ysize), im->channels);
fp=fopen(fname,"ab+");
fprintf(fp,"<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\">");
int a, b;
i_img *im;
i_color rcolor;
- int i,bytes,x,y;
- int info[4];
+ int i;
+ i_img_dim x,y;
+ size_t bytes;
+ i_img_dim info[4];
if ( !getOBJ("image","Imager::ImgRaw",&im) ) { fprintf(stderr,"Error: image is missing\n"); }
if ( !getINT("a",&a) ) { fprintf(stderr,"Error: a is missing\n"); }
bytes=im->bytes;
i_img_info(im,info);
- for(i=0;i<4;i++) { printf("%d: %d\n",i,info[i]); }
- printf("image info:\n size (%d,%d)\n channels (%d)\n",
- im->xsize, im->ysize, im->channels);
+ for(i=0;i<4;i++) { printf("%d: %" i_DF "\n", i, i_DFc(info[i])); }
+ printf("image info:\n size (" i_DFp ")\n channels (%d)\n",
+ i_DFcp(im->xsize, im->ysize), im->channels);
for(y=0;y<im->ysize;y++) for(x=0;x<im->xsize;x++) {
i_gpix(im,x,y,&rcolor);
flines(void *INP) {
i_img *im;
i_color vl;
- int x,y;
+ i_img_dim x,y;
if ( !getOBJ("image","Imager::ImgRaw",&im) ) {
fprintf(stderr,"Error: image is missing\n");
}
fprintf(stderr, "flines: parameters: (im %p)\n",im);
- fprintf(stderr, "flines: image info:\n size (%d,%d)\n channels (%d)\n",
- im->xsize,im->ysize,im->channels);
+ fprintf(stderr, "flines: image info:\n size (" i_DFp ")\n channels (%d)\n",
+ i_DFcp(im->xsize,im->ysize), im->channels);
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);
static
int
-mandel(float x, float y) {
- float xn, yn;
- float xo, yo;
+mandel(double x, double y) {
+ double xn, yn;
+ double xo, yo;
int iter = 1;
/* Z(n+1) = Z(n) ^2 + c */
void mandlebrot(void *INP) {
i_img *im;
- int i,bytes,x,y;
+ int i;
+ i_img_dim x,y;
int idx;
- float xs, ys;
- float div;
+ double xs, ys;
+ double div;
i_color icl[256];
srand(12235);
if ( !getOBJ("image","Imager::ImgRaw",&im) ) { fprintf(stderr,"Error: image is missing\n"); }
fprintf(stderr,"mandlebrot: parameters: (im %p)\n",im);
- bytes=im->bytes;
- fprintf(stderr, "mandlebrot: image info:\n size (%d,%d)\n channels (%d)\n",
- im->xsize,im->ysize,im->channels);
+ fprintf(stderr, "mandlebrot: image info:\n size (" i_DFp ")\n channels (%d)\n",
+ i_DFcp(im->xsize,im->ysize),im->channels);
div = 2.5;
xs = 0.8*div;
=cut
*/
void i_push_error(int code, char const *msg) {
- int size = strlen(msg)+1;
+ size_t size = strlen(msg)+1;
if (error_sp <= 0)
/* bad, bad programmer */
failed_cb(error_stack + error_sp);
if (failures_fatal) {
int sp;
- int total; /* total length of error messages */
+ size_t total; /* total length of error messages */
char *full; /* full message for logging */
if (argv0)
fprintf(stderr, "%s: ", argv0);
i_fatal() */
total = 1; /* remember the NUL */
for (sp = error_sp; error_stack[sp].msg; ++sp) {
- total += strlen(error_stack[sp].msg) + 2;
+ size_t new_total += strlen(error_stack[sp].msg) + 2;
+ if (new_total < total) {
+ /* overflow, somehow */
+ break;
+ }
}
full = mymalloc(total);
if (!full) {
gif - zless /usr/share/doc/libungif4g/gif89.txt.gz
bmp - fileformatdocs/bmp.txt (and MSDN)
ico - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp
+
+TGA
+
+http://paulbourke.net/dataformats/tga/
+
--- /dev/null
+
+
+
+
+ Cover Sheet for the GIF89a Specification
+
+
+ DEFERRED CLEAR CODE IN LZW COMPRESSION
+
+ There has been confusion about where clear codes can be found in the
+ data stream. As the specification says, they may appear at anytime. There
+ is not a requirement to send a clear code when the string table is full.
+
+ It is the encoder's decision as to when the table should be cleared. When
+ the table is full, the encoder can chose to use the table as is, making no
+ changes to it until the encoder chooses to clear it. The encoder during
+ this time sends out codes that are of the maximum Code Size.
+
+ As we can see from the above, when the decoder's table is full, it must
+ not change the table until a clear code is received. The Code Size is that
+ of the maximum Code Size. Processing other than this is done normally.
+
+ Because of a large base of decoders that do not handle the decompression in
+ this manner, we ask developers of GIF encoding software to NOT implement
+ this feature until at least January 1991 and later if they see that their
+ particular market is not ready for it. This will give developers of GIF
+ decoding software time to implement this feature and to get it into the
+ hands of their clients before the decoders start "breaking" on the new
+ GIF's. It is not required that encoders change their software to take
+ advantage of the deferred clear code, but it is for decoders.
+
+ APPLICATION EXTENSION BLOCK - APPLICATION IDENTIFIER
+
+ There will be a Courtesy Directory file located on CompuServe in the PICS
+ forum. This directory will contain Application Identifiers for Application
+ Extension Blocks that have been used by developers of GIF applications.
+ This file is intended to help keep developers that wish to create
+ Application Extension Blocks from using the same Application Identifiers.
+ This is not an official directory; it is for voluntary participation only
+ and does not guarantee that someone will not use the same identifier.
+
+ E-Mail can be sent to Larry Wood (forum manager of PICS) indicating the
+ request for inclusion in this file with an identifier.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GRAPHICS INTERCHANGE FORMAT(sm)
+
+ Version 89a
+
+ (c)1987,1988,1989,1990
+
+ Copyright
+ CompuServe Incorporated
+ Columbus, Ohio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CompuServe Incorporated Graphics Interchange Format
+Document Date : 31 July 1990 Programming Reference
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+Disclaimer................................................................. 1
+
+Foreword................................................................... 1
+
+Licensing.................................................................. 1
+
+About the Document......................................................... 2
+
+General Description........................................................ 2
+
+Version Numbers............................................................ 2
+
+The Encoder................................................................ 3
+
+The Decoder................................................................ 3
+
+Compliance................................................................. 3
+
+About Recommendations...................................................... 4
+
+About Color Tables......................................................... 4
+
+Blocks, Extensions and Scope............................................... 4
+
+Block Sizes................................................................ 5
+
+Using GIF as an embedded protocol.......................................... 5
+
+Data Sub-blocks............................................................ 5
+
+Block Terminator........................................................... 6
+
+Header..................................................................... 7
+
+Logical Screen Descriptor.................................................. 8
+
+Global Color Table......................................................... 10
+
+Image Descriptor........................................................... 11
+
+Local Color Table.......................................................... 13
+
+Table Based Image Data..................................................... 14
+
+Graphic Control Extension.................................................. 15
+
+Comment Extension.......................................................... 17
+
+Plain Text Extension....................................................... 18
+
+Application Extension...................................................... 21
+
+Trailer.................................................................... 23
+
+
+
+
+
+
+
+
+
+
+
+Quick Reference Table...................................................... 24
+
+GIF Grammar................................................................ 25
+
+Glossary................................................................... 27
+
+Conventions................................................................ 28
+
+Interlaced Images.......................................................... 29
+
+Variable-Length-Code LZW Compression....................................... 30
+
+On-line Capabilities Dialogue.............................................. 33
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+1. Disclaimer.
+
+The information provided herein is subject to change without notice. In no
+event will CompuServe Incorporated be liable for damages, including any loss of
+revenue, loss of profits or other incidental or consequential damages arising
+out of the use or inability to use the information; CompuServe Incorporated
+makes no claim as to the suitability of the information.
+
+
+2. Foreword.
+
+This document defines the Graphics Interchange Format(sm). The specification
+given here defines version 89a, which is an extension of version 87a.
+
+The Graphics Interchange Format(sm) as specified here should be considered
+complete; any deviation from it should be considered invalid, including but not
+limited to, the use of reserved or undefined fields within control or data
+blocks, the inclusion of extraneous data within or between blocks, the use of
+methods or algorithms not specifically listed as part of the format, etc. In
+general, any and all deviations, extensions or modifications not specified in
+this document should be considered to be in violation of the format and should
+be avoided.
+
+
+3. Licensing.
+
+The Graphics Interchange Format(c) is the copyright property of CompuServe
+Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
+enhance, alter, modify or change in any way the definition of the format.
+
+CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
+license for the use of the Graphics Interchange Format(sm) in computer
+software; computer software utilizing GIF(sm) must acknowledge ownership of the
+Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
+User and Technical Documentation. Computer software utilizing GIF, which is
+distributed or may be distributed without User or Technical Documentation must
+display to the screen or printer a message acknowledging ownership of the
+Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
+this case, the acknowledgement may be displayed in an opening screen or leading
+banner, or a closing screen or trailing banner. A message such as the following
+may be used:
+
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+For further information, please contact :
+
+ CompuServe Incorporated
+ Graphics Technology Department
+ 5000 Arlington Center Boulevard
+ Columbus, Ohio 43220
+ U. S. A.
+
+CompuServe Incorporated maintains a mailing list with all those individuals and
+organizations who wish to receive copies of this document when it is corrected
+
+
+
+
+
+
+
+ 2
+
+
+or revised. This service is offered free of charge; please provide us with your
+mailing address.
+
+
+4. About the Document.
+
+This document describes in detail the definition of the Graphics Interchange
+Format. This document is intended as a programming reference; it is
+recommended that the entire document be read carefully before programming,
+because of the interdependence of the various parts. There is an individual
+section for each of the Format blocks. Within each section, the sub-section
+labeled Required Version refers to the version number that an encoder will have
+to use if the corresponding block is used in the Data Stream. Within each
+section, a diagram describes the individual fields in the block; the diagrams
+are drawn vertically; top bytes in the diagram appear first in the Data Stream.
+Bits within a byte are drawn most significant on the left end. Multi-byte
+numeric fields are ordered Least Significant Byte first. Numeric constants are
+represented as Hexadecimal numbers, preceded by "0x". Bit fields within a byte
+are described in order from most significant bits to least significant bits.
+
+
+5. General Description.
+
+The Graphics Interchange Format(sm) defines a protocol intended for the on-line
+transmission and interchange of raster graphic data in a way that is
+independent of the hardware used in their creation or display.
+
+The Graphics Interchange Format is defined in terms of blocks and sub-blocks
+which contain relevant parameters and data used in the reproduction of a
+graphic. A GIF Data Stream is a sequence of protocol blocks and sub-blocks
+representing a collection of graphics. In general, the graphics in a Data
+Stream are assumed to be related to some degree, and to share some control
+information; it is recommended that encoders attempt to group together related
+graphics in order to minimize hardware changes during processing and to
+minimize control information overhead. For the same reason, unrelated graphics
+or graphics which require resetting hardware parameters should be encoded
+separately to the extent possible.
+
+A Data Stream may originate locally, as when read from a file, or it may
+originate remotely, as when transmitted over a data communications line. The
+Format is defined with the assumption that an error-free Transport Level
+Protocol is used for communications; the Format makes no provisions for
+error-detection and error-correction.
+
+The GIF Data Stream must be interpreted in context, that is, the application
+program must rely on information external to the Data Stream to invoke the
+decoder process.
+
+
+6. Version Numbers.
+
+The version number in the Header of a Data Stream is intended to identify the
+minimum set of capabilities required of a decoder in order to fully process the
+Data Stream. An encoder should use the earliest possible version number that
+includes all the blocks used in the Data Stream. Within each block section in
+this document, there is an entry labeled Required Version which specifies the
+
+
+
+
+
+
+
+ 3
+
+
+earliest version number that includes the corresponding block. The encoder
+should make every attempt to use the earliest version number covering all the
+blocks in the Data Stream; the unnecessary use of later version numbers will
+hinder processing by some decoders.
+
+
+7. The Encoder.
+
+The Encoder is the program used to create a GIF Data Stream. From raster data
+and other information, the encoder produces the necessary control and data
+blocks needed for reproducing the original graphics.
+
+The encoder has the following primary responsibilities.
+
+ - Include in the Data Stream all the necessary information to
+ reproduce the graphics.
+
+ - Insure that a Data Stream is labeled with the earliest possible
+ Version Number that will cover the definition of all the blocks in
+ it; this is to ensure that the largest number of decoders can
+ process the Data Stream.
+
+ - Ensure encoding of the graphics in such a way that the decoding
+ process is optimized. Avoid redundant information as much as
+ possible.
+
+ - To the extent possible, avoid grouping graphics which might
+ require resetting hardware parameters during the decoding process.
+
+ - Set to zero (off) each of the bits of each and every field
+ designated as reserved. Note that some fields in the Logical Screen
+ Descriptor and the Image Descriptor were reserved under Version
+ 87a, but are used under version 89a.
+
+
+8. The Decoder.
+
+The Decoder is the program used to process a GIF Data Stream. It processes the
+Data Stream sequentially, parsing the various blocks and sub-blocks, using the
+control information to set hardware and process parameters and interpreting the
+data to render the graphics.
+
+The decoder has the following primary responsibilities.
+
+ - Process each graphic in the Data Stream in sequence, without
+ delays other than those specified in the control information.
+
+ - Set its hardware parameters to fit, as closely as possible, the
+ control information contained in the Data Stream.
+
+
+9. Compliance.
+
+An encoder or a decoder is said to comply with a given version of the Graphics
+Interchange Format if and only if it fully conforms with and correctly
+implements the definition of the standard associated with that version. An
+
+
+
+
+
+
+
+ 4
+
+
+encoder or a decoder may be compliant with a given version number and not
+compliant with some subsequent version.
+
+
+10. About Recommendations.
+
+Each block section in this document contains an entry labeled Recommendation;
+this section lists a set of recommendations intended to guide and organize the
+use of the particular blocks. Such recommendations are geared towards making
+the functions of encoders and decoders more efficient, as well as making
+optimal use of the communications bandwidth. It is advised that these
+recommendations be followed.
+
+
+11. About Color Tables.
+
+The GIF format utilizes color tables to render raster-based graphics. A color
+table can have one of two different scopes: global or local. A Global Color
+Table is used by all those graphics in the Data Stream which do not have a
+Local Color Table associated with them. The scope of the Global Color Table is
+the entire Data Stream. A Local Color Table is always associated with the
+graphic that immediately follows it; the scope of a Local Color Table is
+limited to that single graphic. A Local Color Table supersedes a Global Color
+Table, that is, if a Data Stream contains a Global Color Table, and an image
+has a Local Color Table associated with it, the decoder must save the Global
+Color Table, use the Local Color Table to render the image, and then restore
+the Global Color Table. Both types of color tables are optional, making it
+possible for a Data Stream to contain numerous graphics without a color table
+at all. For this reason, it is recommended that the decoder save the last
+Global Color Table used until another Global Color Table is encountered. In
+this way, a Data Stream which does not contain either a Global Color Table or
+a Local Color Table may be processed using the last Global Color Table saved.
+If a Global Color Table from a previous Stream is used, that table becomes the
+Global Color Table of the present Stream. This is intended to reduce the
+overhead incurred by color tables. In particular, it is recommended that an
+encoder use only one Global Color Table if all the images in related Data
+Streams can be rendered with the same table. If no color table is available at
+all, the decoder is free to use a system color table or a table of its own. In
+that case, the decoder may use a color table with as many colors as its
+hardware is able to support; it is recommended that such a table have black and
+white as its first two entries, so that monochrome images can be rendered
+adequately.
+
+The Definition of the GIF Format allows for a Data Stream to contain only the
+Header, the Logical Screen Descriptor, a Global Color Table and the GIF
+Trailer. Such a Data Stream would be used to load a decoder with a Global Color
+Table, in preparation for subsequent Data Streams without a color table at all.
+
+
+12. Blocks, Extensions and Scope.
+
+Blocks can be classified into three groups : Control, Graphic-Rendering and
+Special Purpose. Control blocks, such as the Header, the Logical Screen
+Descriptor, the Graphic Control Extension and the Trailer, contain information
+used to control the process of the Data Stream or information used in setting
+hardware parameters. Graphic-Rendering blocks such as the Image Descriptor and
+
+
+
+
+
+
+
+ 5
+
+
+the Plain Text Extension contain information and data used to render a graphic
+on the display device. Special Purpose blocks such as the Comment Extension and
+the Application Extension are neither used to control the process of the Data
+Stream nor do they contain information or data used to render a graphic on the
+display device. With the exception of the Logical Screen Descriptor and the
+Global Color Table, whose scope is the entire Data Stream, all other Control
+blocks have a limited scope, restricted to the Graphic-Rendering block that
+follows them. Special Purpose blocks do not delimit the scope of any Control
+blocks; Special Purpose blocks are transparent to the decoding process.
+Graphic-Rendering blocks and extensions are used as scope delimiters for
+Control blocks and extensions. The labels used to identify labeled blocks fall
+into three ranges : 0x00-0x7F (0-127) are the Graphic Rendering blocks,
+excluding the Trailer (0x3B); 0x80-0xF9 (128-249) are the Control blocks;
+0xFA-0xFF (250-255) are the Special Purpose blocks. These ranges are defined so
+that decoders can handle block scope by appropriately identifying block labels,
+even when the block itself cannot be processed.
+
+
+13. Block Sizes.
+
+The Block Size field in a block, counts the number of bytes remaining in the
+block, not counting the Block Size field itself, and not counting the Block
+Terminator, if one is to follow. Blocks other than Data Blocks are intended to
+be of fixed length; the Block Size field is provided in order to facilitate
+skipping them, not to allow their size to change in the future. Data blocks
+and sub-blocks are of variable length to accommodate the amount of data.
+
+
+14. Using GIF as an embedded protocol.
+
+As an embedded protocol, GIF may be part of larger application protocols,
+within which GIF is used to render graphics. In such a case, the application
+protocol could define a block within which the GIF Data Stream would be
+contained. The application program would then invoke a GIF decoder upon
+encountering a block of type GIF. This approach is recommended in favor of
+using Application Extensions, which become overhead for all other applications
+that do not process them. Because a GIF Data Stream must be processed in
+context, the application must rely on some means of identifying the GIF Data
+Stream outside of the Stream itself.
+
+
+15. Data Sub-blocks.
+
+ a. Description. Data Sub-blocks are units containing data. They do not
+ have a label, these blocks are processed in the context of control
+ blocks, wherever data blocks are specified in the format. The first byte
+ of the Data sub-block indicates the number of data bytes to follow. A
+ data sub-block may contain from 0 to 255 data bytes. The size of the
+ block does not account for the size byte itself, therefore, the empty
+ sub-block is one whose size field contains 0x00.
+
+ b. Required Version. 87a.
+
+
+
+
+
+
+
+
+
+
+
+ 6
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Block Size Byte
+ +---------------+
+ 1 | |
+ +- -+
+ 2 | |
+ +- -+
+ 3 | |
+ +- -+
+ | | Data Values Byte
+ +- -+
+ up | |
+ +- . . . . -+
+ to | |
+ +- -+
+ | |
+ +- -+
+255 | |
+ +---------------+
+
+ i) Block Size - Number of bytes in the Data Sub-block; the size
+ must be within 0 and 255 bytes, inclusive.
+
+ ii) Data Values - Any 8-bit value. There must be exactly as many
+ Data Values as specified by the Block Size field.
+
+ d. Extensions and Scope. This type of block always occurs as part of a
+ larger unit. It does not have a scope of itself.
+
+ e. Recommendation. None.
+
+
+16. Block Terminator.
+
+ a. Description. This zero-length Data Sub-block is used to terminate a
+ sequence of Data Sub-blocks. It contains a single byte in the position of
+ the Block Size field and does not contain data.
+
+ b. Required Version. 87a.
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Block Size Byte
+ +---------------+
+
+ i) Block Size - Number of bytes in the Data Sub-block; this field
+ contains the fixed value 0x00.
+
+ ii) Data Values - This block does not contain any data.
+
+
+
+
+
+
+
+
+
+ 7
+
+
+ d. Extensions and Scope. This block terminates the immediately preceding
+ sequence of Data Sub-blocks. This block cannot be modified by any
+ extension.
+
+ e. Recommendation. None.
+
+
+17. Header.
+
+ a. Description. The Header identifies the GIF Data Stream in context. The
+ Signature field marks the beginning of the Data Stream, and the Version
+ field identifies the set of capabilities required of a decoder to fully
+ process the Data Stream. This block is REQUIRED; exactly one Header must
+ be present per Data Stream.
+
+ b. Required Version. Not applicable. This block is not subject to a
+ version number. This block must appear at the beginning of every Data
+ Stream.
+
+ c. Syntax.
+
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Signature 3 Bytes
+ +- -+
+ 1 | |
+ +- -+
+ 2 | |
+ +---------------+
+ 3 | | Version 3 Bytes
+ +- -+
+ 4 | |
+ +- -+
+ 5 | |
+ +---------------+
+
+ i) Signature - Identifies the GIF Data Stream. This field contains
+ the fixed value 'GIF'.
+
+ ii) Version - Version number used to format the data stream.
+ Identifies the minimum set of capabilities necessary to a decoder
+ to fully process the contents of the Data Stream.
+
+ Version Numbers as of 10 July 1990 : "87a" - May 1987
+ "89a" - July 1989
+
+ Version numbers are ordered numerically increasing on the first two
+ digits starting with 87 (87,88,...,99,00,...,85,86) and
+ alphabetically increasing on the third character (a,...,z).
+
+ iii) Extensions and Scope. The scope of this block is the entire
+ Data Stream. This block cannot be modified by any extension.
+
+
+
+
+
+
+
+
+
+
+ 8
+
+
+ d. Recommendations.
+
+ i) Signature - This field identifies the beginning of the GIF Data
+ Stream; it is not intended to provide a unique signature for the
+ identification of the data. It is recommended that the GIF Data
+ Stream be identified externally by the application. (Refer to
+ Appendix G for on-line identification of the GIF Data Stream.)
+
+ ii) Version - ENCODER : An encoder should use the earliest possible
+ version number that defines all the blocks used in the Data Stream.
+ When two or more Data Streams are combined, the latest of the
+ individual version numbers should be used for the resulting Data
+ Stream. DECODER : A decoder should attempt to process the data
+ stream to the best of its ability; if it encounters a version
+ number which it is not capable of processing fully, it should
+ nevertheless, attempt to process the data stream to the best of its
+ ability, perhaps after warning the user that the data may be
+ incomplete.
+
+
+18. Logical Screen Descriptor.
+
+ a. Description. The Logical Screen Descriptor contains the parameters
+ necessary to define the area of the display device within which the
+ images will be rendered. The coordinates in this block are given with
+ respect to the top-left corner of the virtual screen; they do not
+ necessarily refer to absolute coordinates on the display device. This
+ implies that they could refer to window coordinates in a window-based
+ environment or printer coordinates when a printer is used.
+
+ This block is REQUIRED; exactly one Logical Screen Descriptor must be
+ present per Data Stream.
+
+ b. Required Version. Not applicable. This block is not subject to a
+ version number. This block must appear immediately after the Header.
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Logical Screen Width Unsigned
+ +- -+
+ 1 | |
+ +---------------+
+ 2 | | Logical Screen Height Unsigned
+ +- -+
+ 3 | |
+ +---------------+
+ 4 | | | | | <Packed Fields> See below
+ +---------------+
+ 5 | | Background Color Index Byte
+ +---------------+
+ 6 | | Pixel Aspect Ratio Byte
+ +---------------+
+
+
+
+
+
+
+
+
+
+ 9
+
+
+ <Packed Fields> = Global Color Table Flag 1 Bit
+ Color Resolution 3 Bits
+ Sort Flag 1 Bit
+ Size of Global Color Table 3 Bits
+
+ i) Logical Screen Width - Width, in pixels, of the Logical Screen
+ where the images will be rendered in the displaying device.
+
+ ii) Logical Screen Height - Height, in pixels, of the Logical
+ Screen where the images will be rendered in the displaying device.
+
+ iii) Global Color Table Flag - Flag indicating the presence of a
+ Global Color Table; if the flag is set, the Global Color Table will
+ immediately follow the Logical Screen Descriptor. This flag also
+ selects the interpretation of the Background Color Index; if the
+ flag is set, the value of the Background Color Index field should
+ be used as the table index of the background color. (This field is
+ the most significant bit of the byte.)
+
+ Values : 0 - No Global Color Table follows, the Background
+ Color Index field is meaningless.
+ 1 - A Global Color Table will immediately follow, the
+ Background Color Index field is meaningful.
+
+ iv) Color Resolution - Number of bits per primary color available
+ to the original image, minus 1. This value represents the size of
+ the entire palette from which the colors in the graphic were
+ selected, not the number of colors actually used in the graphic.
+ For example, if the value in this field is 3, then the palette of
+ the original image had 4 bits per primary color available to create
+ the image. This value should be set to indicate the richness of
+ the original palette, even if not every color from the whole
+ palette is available on the source machine.
+
+ v) Sort Flag - Indicates whether the Global Color Table is sorted.
+ If the flag is set, the Global Color Table is sorted, in order of
+ decreasing importance. Typically, the order would be decreasing
+ frequency, with most frequent color first. This assists a decoder,
+ with fewer available colors, in choosing the best subset of colors;
+ the decoder may use an initial segment of the table to render the
+ graphic.
+
+ Values : 0 - Not ordered.
+ 1 - Ordered by decreasing importance, most
+ important color first.
+
+ vi) Size of Global Color Table - If the Global Color Table Flag is
+ set to 1, the value in this field is used to calculate the number
+ of bytes contained in the Global Color Table. To determine that
+ actual size of the color table, raise 2 to [the value of the field
+ + 1]. Even if there is no Global Color Table specified, set this
+ field according to the above formula so that decoders can choose
+ the best graphics mode to display the stream in. (This field is
+ made up of the 3 least significant bits of the byte.)
+
+ vii) Background Color Index - Index into the Global Color Table for
+
+
+
+
+
+
+
+ 10
+
+
+ the Background Color. The Background Color is the color used for
+ those pixels on the screen that are not covered by an image. If the
+ Global Color Table Flag is set to (zero), this field should be zero
+ and should be ignored.
+
+ viii) Pixel Aspect Ratio - Factor used to compute an approximation
+ of the aspect ratio of the pixel in the original image. If the
+ value of the field is not 0, this approximation of the aspect ratio
+ is computed based on the formula:
+
+ Aspect Ratio = (Pixel Aspect Ratio + 15) / 64
+
+ The Pixel Aspect Ratio is defined to be the quotient of the pixel's
+ width over its height. The value range in this field allows
+ specification of the widest pixel of 4:1 to the tallest pixel of
+ 1:4 in increments of 1/64th.
+
+ Values : 0 - No aspect ratio information is given.
+ 1..255 - Value used in the computation.
+
+ d. Extensions and Scope. The scope of this block is the entire Data
+ Stream. This block cannot be modified by any extension.
+
+ e. Recommendations. None.
+
+
+19. Global Color Table.
+
+ a. Description. This block contains a color table, which is a sequence of
+ bytes representing red-green-blue color triplets. The Global Color Table
+ is used by images without a Local Color Table and by Plain Text
+ Extensions. Its presence is marked by the Global Color Table Flag being
+ set to 1 in the Logical Screen Descriptor; if present, it immediately
+ follows the Logical Screen Descriptor and contains a number of bytes
+ equal to
+ 3 x 2^(Size of Global Color Table+1).
+
+ This block is OPTIONAL; at most one Global Color Table may be present
+ per Data Stream.
+
+ b. Required Version. 87a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 11
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +===============+
+ 0 | | Red 0 Byte
+ +- -+
+ 1 | | Green 0 Byte
+ +- -+
+ 2 | | Blue 0 Byte
+ +- -+
+ 3 | | Red 1 Byte
+ +- -+
+ | | Green 1 Byte
+ +- -+
+ up | |
+ +- . . . . -+ ...
+ to | |
+ +- -+
+ | | Green 255 Byte
+ +- -+
+767 | | Blue 255 Byte
+ +===============+
+
+
+ d. Extensions and Scope. The scope of this block is the entire Data
+ Stream. This block cannot be modified by any extension.
+
+ e. Recommendation. None.
+
+
+20. Image Descriptor.
+
+ a. Description. Each image in the Data Stream is composed of an Image
+ Descriptor, an optional Local Color Table, and the image data. Each
+ image must fit within the boundaries of the Logical Screen, as defined
+ in the Logical Screen Descriptor.
+
+ The Image Descriptor contains the parameters necessary to process a table
+ based image. The coordinates given in this block refer to coordinates
+ within the Logical Screen, and are given in pixels. This block is a
+ Graphic-Rendering Block, optionally preceded by one or more Control
+ blocks such as the Graphic Control Extension, and may be optionally
+ followed by a Local Color Table; the Image Descriptor is always followed
+ by the image data.
+
+ This block is REQUIRED for an image. Exactly one Image Descriptor must
+ be present per image in the Data Stream. An unlimited number of images
+ may be present per Data Stream.
+
+ b. Required Version. 87a.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Image Separator Byte
+ +---------------+
+ 1 | | Image Left Position Unsigned
+ +- -+
+ 2 | |
+ +---------------+
+ 3 | | Image Top Position Unsigned
+ +- -+
+ 4 | |
+ +---------------+
+ 5 | | Image Width Unsigned
+ +- -+
+ 6 | |
+ +---------------+
+ 7 | | Image Height Unsigned
+ +- -+
+ 8 | |
+ +---------------+
+ 9 | | | | | | <Packed Fields> See below
+ +---------------+
+
+ <Packed Fields> = Local Color Table Flag 1 Bit
+ Interlace Flag 1 Bit
+ Sort Flag 1 Bit
+ Reserved 2 Bits
+ Size of Local Color Table 3 Bits
+
+ i) Image Separator - Identifies the beginning of an Image
+ Descriptor. This field contains the fixed value 0x2C.
+
+ ii) Image Left Position - Column number, in pixels, of the left edge
+ of the image, with respect to the left edge of the Logical Screen.
+ Leftmost column of the Logical Screen is 0.
+
+ iii) Image Top Position - Row number, in pixels, of the top edge of
+ the image with respect to the top edge of the Logical Screen. Top
+ row of the Logical Screen is 0.
+
+ iv) Image Width - Width of the image in pixels.
+
+ v) Image Height - Height of the image in pixels.
+
+ vi) Local Color Table Flag - Indicates the presence of a Local Color
+ Table immediately following this Image Descriptor. (This field is
+ the most significant bit of the byte.)
+
+
+ Values : 0 - Local Color Table is not present. Use
+ Global Color Table if available.
+ 1 - Local Color Table present, and to follow
+ immediately after this Image Descriptor.
+
+
+
+
+
+
+
+
+ 13
+
+
+ vii) Interlace Flag - Indicates if the image is interlaced. An image
+ is interlaced in a four-pass interlace pattern; see Appendix E for
+ details.
+
+ Values : 0 - Image is not interlaced.
+ 1 - Image is interlaced.
+
+ viii) Sort Flag - Indicates whether the Local Color Table is
+ sorted. If the flag is set, the Local Color Table is sorted, in
+ order of decreasing importance. Typically, the order would be
+ decreasing frequency, with most frequent color first. This assists
+ a decoder, with fewer available colors, in choosing the best subset
+ of colors; the decoder may use an initial segment of the table to
+ render the graphic.
+
+ Values : 0 - Not ordered.
+ 1 - Ordered by decreasing importance, most
+ important color first.
+
+ ix) Size of Local Color Table - If the Local Color Table Flag is
+ set to 1, the value in this field is used to calculate the number
+ of bytes contained in the Local Color Table. To determine that
+ actual size of the color table, raise 2 to the value of the field
+ + 1. This value should be 0 if there is no Local Color Table
+ specified. (This field is made up of the 3 least significant bits
+ of the byte.)
+
+ d. Extensions and Scope. The scope of this block is the Table-based Image
+ Data Block that follows it. This block may be modified by the Graphic
+ Control Extension.
+
+ e. Recommendation. None.
+
+
+21. Local Color Table.
+
+ a. Description. This block contains a color table, which is a sequence of
+ bytes representing red-green-blue color triplets. The Local Color Table
+ is used by the image that immediately follows. Its presence is marked by
+ the Local Color Table Flag being set to 1 in the Image Descriptor; if
+ present, the Local Color Table immediately follows the Image Descriptor
+ and contains a number of bytes equal to
+ 3x2^(Size of Local Color Table+1).
+ If present, this color table temporarily becomes the active color table
+ and the following image should be processed using it. This block is
+ OPTIONAL; at most one Local Color Table may be present per Image
+ Descriptor and its scope is the single image associated with the Image
+ Descriptor that precedes it.
+
+ b. Required Version. 87a.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 14
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +===============+
+ 0 | | Red 0 Byte
+ +- -+
+ 1 | | Green 0 Byte
+ +- -+
+ 2 | | Blue 0 Byte
+ +- -+
+ 3 | | Red 1 Byte
+ +- -+
+ | | Green 1 Byte
+ +- -+
+ up | |
+ +- . . . . -+ ...
+ to | |
+ +- -+
+ | | Green 255 Byte
+ +- -+
+767 | | Blue 255 Byte
+ +===============+
+
+
+ d. Extensions and Scope. The scope of this block is the Table-based Image
+ Data Block that immediately follows it. This block cannot be modified by
+ any extension.
+
+ e. Recommendations. None.
+
+
+22. Table Based Image Data.
+
+ a. Description. The image data for a table based image consists of a
+ sequence of sub-blocks, of size at most 255 bytes each, containing an
+ index into the active color table, for each pixel in the image. Pixel
+ indices are in order of left to right and from top to bottom. Each index
+ must be within the range of the size of the active color table, starting
+ at 0. The sequence of indices is encoded using the LZW Algorithm with
+ variable-length code, as described in Appendix F
+
+ b. Required Version. 87a.
+
+ c. Syntax. The image data format is as follows:
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ | | LZW Minimum Code Size Byte
+ +---------------+
+
+ +===============+
+ | |
+ / / Image Data Data Sub-blocks
+ | |
+ +===============+
+
+
+
+
+
+
+
+
+ 15
+
+
+ i) LZW Minimum Code Size. This byte determines the initial number
+ of bits used for LZW codes in the image data, as described in
+ Appendix F.
+
+ d. Extensions and Scope. This block has no scope, it contains raster
+ data. Extensions intended to modify a Table-based image must appear
+ before the corresponding Image Descriptor.
+
+ e. Recommendations. None.
+
+
+23. Graphic Control Extension.
+
+ a. Description. The Graphic Control Extension contains parameters used
+ when processing a graphic rendering block. The scope of this extension is
+ the first graphic rendering block to follow. The extension contains only
+ one data sub-block.
+
+ This block is OPTIONAL; at most one Graphic Control Extension may precede
+ a graphic rendering block. This is the only limit to the number of
+ Graphic Control Extensions that may be contained in a Data Stream.
+
+ b. Required Version. 89a.
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Extension Introducer Byte
+ +---------------+
+ 1 | | Graphic Control Label Byte
+ +---------------+
+
+ +---------------+
+ 0 | | Block Size Byte
+ +---------------+
+ 1 | | | | | <Packed Fields> See below
+ +---------------+
+ 2 | | Delay Time Unsigned
+ +- -+
+ 3 | |
+ +---------------+
+ 4 | | Transparent Color Index Byte
+ +---------------+
+
+ +---------------+
+ 0 | | Block Terminator Byte
+ +---------------+
+
+
+ <Packed Fields> = Reserved 3 Bits
+ Disposal Method 3 Bits
+ User Input Flag 1 Bit
+ Transparent Color Flag 1 Bit
+
+ i) Extension Introducer - Identifies the beginning of an extension
+
+
+
+
+
+
+
+ 16
+
+
+ block. This field contains the fixed value 0x21.
+
+ ii) Graphic Control Label - Identifies the current block as a
+ Graphic Control Extension. This field contains the fixed value
+ 0xF9.
+
+ iii) Block Size - Number of bytes in the block, after the Block
+ Size field and up to but not including the Block Terminator. This
+ field contains the fixed value 4.
+
+ iv) Disposal Method - Indicates the way in which the graphic is to
+ be treated after being displayed.
+
+ Values : 0 - No disposal specified. The decoder is
+ not required to take any action.
+ 1 - Do not dispose. The graphic is to be left
+ in place.
+ 2 - Restore to background color. The area used by the
+ graphic must be restored to the background color.
+ 3 - Restore to previous. The decoder is required to
+ restore the area overwritten by the graphic with
+ what was there prior to rendering the graphic.
+ 4-7 - To be defined.
+
+ v) User Input Flag - Indicates whether or not user input is
+ expected before continuing. If the flag is set, processing will
+ continue when user input is entered. The nature of the User input
+ is determined by the application (Carriage Return, Mouse Button
+ Click, etc.).
+
+ Values : 0 - User input is not expected.
+ 1 - User input is expected.
+
+ When a Delay Time is used and the User Input Flag is set,
+ processing will continue when user input is received or when the
+ delay time expires, whichever occurs first.
+
+ vi) Transparency Flag - Indicates whether a transparency index is
+ given in the Transparent Index field. (This field is the least
+ significant bit of the byte.)
+
+ Values : 0 - Transparent Index is not given.
+ 1 - Transparent Index is given.
+
+ vii) Delay Time - If not 0, this field specifies the number of
+ hundredths (1/100) of a second to wait before continuing with the
+ processing of the Data Stream. The clock starts ticking immediately
+ after the graphic is rendered. This field may be used in
+ conjunction with the User Input Flag field.
+
+ viii) Transparency Index - The Transparency Index is such that when
+ encountered, the corresponding pixel of the display device is not
+ modified and processing goes on to the next pixel. The index is
+ present if and only if the Transparency Flag is set to 1.
+
+ ix) Block Terminator - This zero-length data block marks the end of
+
+
+
+
+
+
+
+ 17
+
+ the Graphic Control Extension.
+
+ d. Extensions and Scope. The scope of this Extension is the graphic
+ rendering block that follows it; it is possible for other extensions to
+ be present between this block and its target. This block can modify the
+ Image Descriptor Block and the Plain Text Extension.
+
+ e. Recommendations.
+
+ i) Disposal Method - The mode Restore To Previous is intended to be
+ used in small sections of the graphic; the use of this mode imposes
+ severe demands on the decoder to store the section of the graphic
+ that needs to be saved. For this reason, this mode should be used
+ sparingly. This mode is not intended to save an entire graphic or
+ large areas of a graphic; when this is the case, the encoder should
+ make every attempt to make the sections of the graphic to be
+ restored be separate graphics in the data stream. In the case where
+ a decoder is not capable of saving an area of a graphic marked as
+ Restore To Previous, it is recommended that a decoder restore to
+ the background color.
+
+ ii) User Input Flag - When the flag is set, indicating that user
+ input is expected, the decoder may sound the bell (0x07) to alert
+ the user that input is being expected. In the absence of a
+ specified Delay Time, the decoder should wait for user input
+ indefinitely. It is recommended that the encoder not set the User
+ Input Flag without a Delay Time specified.
+
+
+24. Comment Extension.
+
+ a. Description. The Comment Extension contains textual information which
+ is not part of the actual graphics in the GIF Data Stream. It is suitable
+ for including comments about the graphics, credits, descriptions or any
+ other type of non-control and non-graphic data. The Comment Extension
+ may be ignored by the decoder, or it may be saved for later processing;
+ under no circumstances should a Comment Extension disrupt or interfere
+ with the processing of the Data Stream.
+
+ This block is OPTIONAL; any number of them may appear in the Data Stream.
+
+ b. Required Version. 89a.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 18
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Extension Introducer Byte
+ +---------------+
+ 1 | | Comment Label Byte
+ +---------------+
+
+ +===============+
+ | |
+ N | | Comment Data Data Sub-blocks
+ | |
+ +===============+
+
+ +---------------+
+ 0 | | Block Terminator Byte
+ +---------------+
+
+ i) Extension Introducer - Identifies the beginning of an extension
+ block. This field contains the fixed value 0x21.
+
+ ii) Comment Label - Identifies the block as a Comment Extension.
+ This field contains the fixed value 0xFE.
+
+ iii) Comment Data - Sequence of sub-blocks, each of size at most
+ 255 bytes and at least 1 byte, with the size in a byte preceding
+ the data. The end of the sequence is marked by the Block
+ Terminator.
+
+ iv) Block Terminator - This zero-length data block marks the end of
+ the Comment Extension.
+
+ d. Extensions and Scope. This block does not have scope. This block
+ cannot be modified by any extension.
+
+ e. Recommendations.
+
+ i) Data - This block is intended for humans. It should contain
+ text using the 7-bit ASCII character set. This block should
+ not be used to store control information for custom processing.
+
+ ii) Position - This block may appear at any point in the Data
+ Stream at which a block can begin; however, it is recommended that
+ Comment Extensions do not interfere with Control or Data blocks;
+ they should be located at the beginning or at the end of the Data
+ Stream to the extent possible.
+
+
+25. Plain Text Extension.
+
+ a. Description. The Plain Text Extension contains textual data and the
+ parameters necessary to render that data as a graphic, in a simple form.
+ The textual data will be encoded with the 7-bit printable ASCII
+ characters. Text data are rendered using a grid of character cells
+
+
+
+
+
+
+
+
+ 19
+
+
+ defined by the parameters in the block fields. Each character is rendered
+ in an individual cell. The textual data in this block is to be rendered
+ as mono-spaced characters, one character per cell, with a best fitting
+ font and size. For further information, see the section on
+ Recommendations below. The data characters are taken sequentially from
+ the data portion of the block and rendered within a cell, starting with
+ the upper left cell in the grid and proceeding from left to right and
+ from top to bottom. Text data is rendered until the end of data is
+ reached or the character grid is filled. The Character Grid contains an
+ integral number of cells; in the case that the cell dimensions do not
+ allow for an integral number, fractional cells must be discarded; an
+ encoder must be careful to specify the grid dimensions accurately so that
+ this does not happen. This block requires a Global Color Table to be
+ available; the colors used by this block reference the Global Color Table
+ in the Stream if there is one, or the Global Color Table from a previous
+ Stream, if one was saved. This block is a graphic rendering block,
+ therefore it may be modified by a Graphic Control Extension. This block
+ is OPTIONAL; any number of them may appear in the Data Stream.
+
+ b. Required Version. 89a.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 20
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Extension Introducer Byte
+ +---------------+
+ 1 | | Plain Text Label Byte
+ +---------------+
+
+ +---------------+
+ 0 | | Block Size Byte
+ +---------------+
+ 1 | | Text Grid Left Position Unsigned
+ +- -+
+ 2 | |
+ +---------------+
+ 3 | | Text Grid Top Position Unsigned
+ +- -+
+ 4 | |
+ +---------------+
+ 5 | | Text Grid Width Unsigned
+ +- -+
+ 6 | |
+ +---------------+
+ 7 | | Text Grid Height Unsigned
+ +- -+
+ 8 | |
+ +---------------+
+ 9 | | Character Cell Width Byte
+ +---------------+
+ 10 | | Character Cell Height Byte
+ +---------------+
+ 11 | | Text Foreground Color Index Byte
+ +---------------+
+ 12 | | Text Background Color Index Byte
+ +---------------+
+
+ +===============+
+ | |
+ N | | Plain Text Data Data Sub-blocks
+ | |
+ +===============+
+
+ +---------------+
+ 0 | | Block Terminator Byte
+ +---------------+
+
+ i) Extension Introducer - Identifies the beginning of an extension
+ block. This field contains the fixed value 0x21.
+
+ ii) Plain Text Label - Identifies the current block as a Plain Text
+ Extension. This field contains the fixed value 0x01.
+
+ iii) Block Size - Number of bytes in the extension, after the Block
+ Size field and up to but not including the beginning of the data
+ portion. This field contains the fixed value 12.
+
+
+
+
+
+
+
+ 21
+
+
+ iv) Text Grid Left Position - Column number, in pixels, of the left
+ edge of the text grid, with respect to the left edge of the Logical
+ Screen.
+
+ v) Text Grid Top Position - Row number, in pixels, of the top edge
+ of the text grid, with respect to the top edge of the Logical
+ Screen.
+
+ vi) Image Grid Width - Width of the text grid in pixels.
+
+ vii) Image Grid Height - Height of the text grid in pixels.
+
+ viii) Character Cell Width - Width, in pixels, of each cell in the
+ grid.
+
+ ix) Character Cell Height - Height, in pixels, of each cell in the
+ grid.
+
+ x) Text Foreground Color Index - Index into the Global Color Table
+ to be used to render the text foreground.
+
+ xi) Text Background Color Index - Index into the Global Color Table
+ to be used to render the text background.
+
+ xii) Plain Text Data - Sequence of sub-blocks, each of size at most
+ 255 bytes and at least 1 byte, with the size in a byte preceding
+ the data. The end of the sequence is marked by the Block
+ Terminator.
+
+ xiii) Block Terminator - This zero-length data block marks the end
+ of the Plain Text Data Blocks.
+
+ d. Extensions and Scope. The scope of this block is the Plain Text Data
+ Block contained in it. This block may be modified by the Graphic Control
+ Extension.
+
+ e. Recommendations. The data in the Plain Text Extension is assumed to be
+ preformatted. The selection of font and size is left to the discretion of
+ the decoder. If characters less than 0x20 or greater than 0xf7 are
+ encountered, it is recommended that the decoder display a Space character
+ (0x20). The encoder should use grid and cell dimensions such that an
+ integral number of cells fit in the grid both horizontally as well as
+ vertically. For broadest compatibility, character cell dimensions should
+ be around 8x8 or 8x16 (width x height); consider an image for unusual
+ sized text.
+
+
+26. Application Extension.
+
+ a. Description. The Application Extension contains application-specific
+ information; it conforms with the extension block syntax, as described
+ below, and its block label is 0xFF.
+
+ b. Required Version. 89a.
+
+
+
+
+
+
+
+
+
+ 22
+
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | Extension Introducer Byte
+ +---------------+
+ 1 | | Extension Label Byte
+ +---------------+
+
+ +---------------+
+ 0 | | Block Size Byte
+ +---------------+
+ 1 | |
+ +- -+
+ 2 | |
+ +- -+
+ 3 | | Application Identifier 8 Bytes
+ +- -+
+ 4 | |
+ +- -+
+ 5 | |
+ +- -+
+ 6 | |
+ +- -+
+ 7 | |
+ +- -+
+ 8 | |
+ +---------------+
+ 9 | |
+ +- -+
+ 10 | | Appl. Authentication Code 3 Bytes
+ +- -+
+ 11 | |
+ +---------------+
+
+ +===============+
+ | |
+ | | Application Data Data Sub-blocks
+ | |
+ | |
+ +===============+
+
+ +---------------+
+ 0 | | Block Terminator Byte
+ +---------------+
+
+ i) Extension Introducer - Defines this block as an extension. This
+ field contains the fixed value 0x21.
+
+ ii) Application Extension Label - Identifies the block as an
+ Application Extension. This field contains the fixed value 0xFF.
+
+ iii) Block Size - Number of bytes in this extension block,
+ following the Block Size field, up to but not including the
+ beginning of the Application Data. This field contains the fixed
+ value 11.
+
+
+
+
+
+
+
+ 23
+
+
+ iv) Application Identifier - Sequence of eight printable ASCII
+ characters used to identify the application owning the Application
+ Extension.
+
+ v) Application Authentication Code - Sequence of three bytes used
+ to authenticate the Application Identifier. An Application program
+ may use an algorithm to compute a binary code that uniquely
+ identifies it as the application owning the Application Extension.
+
+
+ d. Extensions and Scope. This block does not have scope. This block
+ cannot be modified by any extension.
+
+ e. Recommendation. None.
+
+
+27. Trailer.
+
+ a. Description. This block is a single-field block indicating the end of
+ the GIF Data Stream. It contains the fixed value 0x3B.
+
+ b. Required Version. 87a.
+
+ c. Syntax.
+
+ 7 6 5 4 3 2 1 0 Field Name Type
+ +---------------+
+ 0 | | GIF Trailer Byte
+ +---------------+
+
+ d. Extensions and Scope. This block does not have scope, it terminates
+ the GIF Data Stream. This block may not be modified by any extension.
+
+ e. Recommendations. None.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 24
+
+
+Appendix
+A. Quick Reference Table.
+
+Block Name Required Label Ext. Vers.
+Application Extension Opt. (*) 0xFF (255) yes 89a
+Comment Extension Opt. (*) 0xFE (254) yes 89a
+Global Color Table Opt. (1) none no 87a
+Graphic Control Extension Opt. (*) 0xF9 (249) yes 89a
+Header Req. (1) none no N/A
+Image Descriptor Opt. (*) 0x2C (044) no 87a (89a)
+Local Color Table Opt. (*) none no 87a
+Logical Screen Descriptor Req. (1) none no 87a (89a)
+Plain Text Extension Opt. (*) 0x01 (001) yes 89a
+Trailer Req. (1) 0x3B (059) no 87a
+
+Unlabeled Blocks
+Header Req. (1) none no N/A
+Logical Screen Descriptor Req. (1) none no 87a (89a)
+Global Color Table Opt. (1) none no 87a
+Local Color Table Opt. (*) none no 87a
+
+Graphic-Rendering Blocks
+Plain Text Extension Opt. (*) 0x01 (001) yes 89a
+Image Descriptor Opt. (*) 0x2C (044) no 87a (89a)
+
+Control Blocks
+Graphic Control Extension Opt. (*) 0xF9 (249) yes 89a
+
+Special Purpose Blocks
+Trailer Req. (1) 0x3B (059) no 87a
+Comment Extension Opt. (*) 0xFE (254) yes 89a
+Application Extension Opt. (*) 0xFF (255) yes 89a
+
+legend: (1) if present, at most one occurrence
+ (*) zero or more occurrences
+ (+) one or more occurrences
+
+Notes : The Header is not subject to Version Numbers.
+(89a) The Logical Screen Descriptor and the Image Descriptor retained their
+syntax from version 87a to version 89a, but some fields reserved under version
+87a are used under version 89a.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 25
+
+
+Appendix
+B. GIF Grammar.
+
+A Grammar is a form of notation to represent the sequence in which certain
+objects form larger objects. A grammar is also used to represent the number of
+objects that can occur at a given position. The grammar given here represents
+the sequence of blocks that form the GIF Data Stream. A grammar is given by
+listing its rules. Each rule consists of the left-hand side, followed by some
+form of equals sign, followed by the right-hand side. In a rule, the
+right-hand side describes how the left-hand side is defined. The right-hand
+side consists of a sequence of entities, with the possible presence of special
+symbols. The following legend defines the symbols used in this grammar for GIF.
+
+Legend: <> grammar word
+ ::= defines symbol
+ * zero or more occurrences
+ + one or more occurrences
+ | alternate element
+ [] optional element
+
+Example:
+
+<GIF Data Stream> ::= Header <Logical Screen> <Data>* Trailer
+
+This rule defines the entity <GIF Data Stream> as follows. It must begin with a
+Header. The Header is followed by an entity called Logical Screen, which is
+defined below by another rule. The Logical Screen is followed by the entity
+Data, which is also defined below by another rule. Finally, the entity Data is
+followed by the Trailer. Since there is no rule defining the Header or the
+Trailer, this means that these blocks are defined in the document. The entity
+Data has a special symbol (*) following it which means that, at this position,
+the entity Data may be repeated any number of times, including 0 times. For
+further reading on this subject, refer to a standard text on Programming
+Languages.
+
+
+The Grammar.
+
+<GIF Data Stream> ::= Header <Logical Screen> <Data>* Trailer
+
+<Logical Screen> ::= Logical Screen Descriptor [Global Color Table]
+
+<Data> ::= <Graphic Block> |
+ <Special-Purpose Block>
+
+<Graphic Block> ::= [Graphic Control Extension] <Graphic-Rendering Block>
+
+<Graphic-Rendering Block> ::= <Table-Based Image> |
+ Plain Text Extension
+
+<Table-Based Image> ::= Image Descriptor [Local Color Table] Image Data
+
+<Special-Purpose Block> ::= Application Extension |
+ Comment Extension
+
+
+
+
+
+
+
+
+
+ 26
+
+
+NOTE : The grammar indicates that it is possible for a GIF Data Stream to
+contain the Header, the Logical Screen Descriptor, a Global Color Table and the
+GIF Trailer. This special case is used to load a GIF decoder with a Global
+Color Table, in preparation for subsequent Data Streams without color tables at
+all.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 27
+
+
+Appendix
+C. Glossary.
+
+Active Color Table - Color table used to render the next graphic. If the next
+graphic is an image which has a Local Color Table associated with it, the
+active color table becomes the Local Color Table associated with that image.
+If the next graphic is an image without a Local Color Table, or a Plain Text
+Extension, the active color table is the Global Color Table associated with the
+Data Stream, if there is one; if there is no Global Color Table in the Data
+Stream, the active color table is a color table saved from a previous Data
+Stream, or one supplied by the decoder.
+
+Block - Collection of bytes forming a protocol unit. In general, the term
+includes labeled and unlabeled blocks, as well as Extensions.
+
+Data Stream - The GIF Data Stream is composed of blocks and sub-blocks
+representing images and graphics, together with control information to render
+them on a display device. All control and data blocks in the Data Stream must
+follow the Header and must precede the Trailer.
+
+Decoder - A program capable of processing a GIF Data Stream to render the
+images and graphics contained in it.
+
+Encoder - A program capable of capturing and formatting image and graphic
+raster data, following the definitions of the Graphics Interchange Format.
+
+Extension - A protocol block labeled by the Extension Introducer 0x21.
+
+Extension Introducer - Label (0x21) defining an Extension.
+
+Graphic - Data which can be rendered on the screen by virtue of some algorithm.
+The term graphic is more general than the term image; in addition to images,
+the term graphic also includes data such as text, which is rendered using
+character bit-maps.
+
+Image - Data representing a picture or a drawing; an image is represented by an
+array of pixels called the raster of the image.
+
+Raster - Array of pixel values representing an image.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 28
+
+
+Appendix
+D. Conventions.
+
+Animation - The Graphics Interchange Format is not intended as a platform for
+animation, even though it can be done in a limited way.
+
+Byte Ordering - Unless otherwise stated, multi-byte numeric fields are ordered
+with the Least Significant Byte first.
+
+Color Indices - Color indices always refer to the active color table, either
+the Global Color Table or the Local Color Table.
+
+Color Order - Unless otherwise stated, all triple-component RGB color values
+are specified in Red-Green-Blue order.
+
+Color Tables - Both color tables, the Global and the Local, are optional; if
+present, the Global Color Table is to be used with every image in the Data
+Stream for which a Local Color Table is not given; if present, a Local Color
+Table overrides the Global Color Table. However, if neither color table is
+present, the application program is free to use an arbitrary color table. If
+the graphics in several Data Streams are related and all use the same color
+table, an encoder could place the color table as the Global Color Table in the
+first Data Stream and leave subsequent Data Streams without a Global Color
+Table or any Local Color Tables; in this way, the overhead for the table is
+eliminated. It is recommended that the decoder save the previous Global Color
+Table to be used with the Data Stream that follows, in case it does not contain
+either a Global Color Table or any Local Color Tables. In general, this allows
+the application program to use past color tables, significantly reducing
+transmission overhead.
+
+Extension Blocks - Extensions are defined using the Extension Introducer code
+to mark the beginning of the block, followed by a block label, identifying the
+type of extension. Extension Codes are numbers in the range from 0x00 to 0xFF,
+inclusive. Special purpose extensions are transparent to the decoder and may be
+omitted when transmitting the Data Stream on-line. The GIF capabilities
+dialogue makes the provision for the receiver to request the transmission of
+all blocks; the default state in this regard is no transmission of Special
+purpose blocks.
+
+Reserved Fields - All Reserved Fields are expected to have each bit set to zero
+(off).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 29
+
+
+Appendix
+E. Interlaced Images.
+
+The rows of an Interlaced images are arranged in the following order:
+
+ Group 1 : Every 8th. row, starting with row 0. (Pass 1)
+ Group 2 : Every 8th. row, starting with row 4. (Pass 2)
+ Group 3 : Every 4th. row, starting with row 2. (Pass 3)
+ Group 4 : Every 2nd. row, starting with row 1. (Pass 4)
+
+The Following example illustrates how the rows of an interlaced image are
+ordered.
+
+ Row Number Interlace Pass
+
+ 0 ----------------------------------------- 1
+ 1 ----------------------------------------- 4
+ 2 ----------------------------------------- 3
+ 3 ----------------------------------------- 4
+ 4 ----------------------------------------- 2
+ 5 ----------------------------------------- 4
+ 6 ----------------------------------------- 3
+ 7 ----------------------------------------- 4
+ 8 ----------------------------------------- 1
+ 9 ----------------------------------------- 4
+ 10 ----------------------------------------- 3
+ 11 ----------------------------------------- 4
+ 12 ----------------------------------------- 2
+ 13 ----------------------------------------- 4
+ 14 ----------------------------------------- 3
+ 15 ----------------------------------------- 4
+ 16 ----------------------------------------- 1
+ 17 ----------------------------------------- 4
+ 18 ----------------------------------------- 3
+ 19 ----------------------------------------- 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 30
+
+
+Appendix
+F. Variable-Length-Code LZW Compression.
+
+The Variable-Length-Code LZW Compression is a variation of the Lempel-Ziv
+Compression algorithm in which variable-length codes are used to replace
+patterns detected in the original data. The algorithm uses a code or
+translation table constructed from the patterns encountered in the original
+data; each new pattern is entered into the table and its index is used to
+replace it in the compressed stream.
+
+The compressor takes the data from the input stream and builds a code or
+translation table with the patterns as it encounters them; each new pattern is
+entered into the code table and its index is added to the output stream; when a
+pattern is encountered which had been detected since the last code table
+refresh, its index from the code table is put on the output stream, thus
+achieving the data compression. The expander takes input from the compressed
+data stream and builds the code or translation table from it; as the compressed
+data stream is processed, codes are used to index into the code table and the
+corresponding data is put on the decompressed output stream, thus achieving
+data decompression. The details of the algorithm are explained below. The
+Variable-Length-Code aspect of the algorithm is based on an initial code size
+(LZW-initial code size), which specifies the initial number of bits used for
+the compression codes. When the number of patterns detected by the compressor
+in the input stream exceeds the number of patterns encodable with the current
+number of bits, the number of bits per LZW code is increased by one.
+
+The Raster Data stream that represents the actual output image can be
+represented as:
+
+ 7 6 5 4 3 2 1 0
+ +---------------+
+ | LZW code size |
+ +---------------+
+
+ +---------------+ ----+
+ | block size | |
+ +---------------+ |
+ | | +-- Repeated as many
+ | data bytes | | times as necessary.
+ | | |
+ +---------------+ ----+
+
+ . . . . . . ------- The code that terminates the LZW
+ compressed data must appear before
+ Block Terminator.
+ +---------------+
+ |0 0 0 0 0 0 0 0| Block Terminator
+ +---------------+
+
+The conversion of the image from a series of pixel values to a transmitted or
+stored character stream involves several steps. In brief these steps are:
+
+1. Establish the Code Size - Define the number of bits needed to represent the
+actual data.
+
+2. Compress the Data - Compress the series of image pixels to a series of
+
+
+
+
+
+
+
+ 31
+
+
+compression codes.
+
+3. Build a Series of Bytes - Take the set of compression codes and convert to a
+string of 8-bit bytes.
+
+4. Package the Bytes - Package sets of bytes into blocks preceded by character
+counts and output.
+
+ESTABLISH CODE SIZE
+
+The first byte of the Compressed Data stream is a value indicating the minimum
+number of bits required to represent the set of actual pixel values. Normally
+this will be the same as the number of color bits. Because of some algorithmic
+constraints however, black & white images which have one color bit must be
+indicated as having a code size of 2.
+This code size value also implies that the compression codes must start out one
+bit longer.
+
+COMPRESSION
+
+The LZW algorithm converts a series of data values into a series of codes which
+may be raw values or a code designating a series of values. Using text
+characters as an analogy, the output code consists of a character or a code
+representing a string of characters.
+
+The LZW algorithm used in GIF matches algorithmically with the standard LZW
+algorithm with the following differences:
+
+1. A special Clear code is defined which resets all compression/decompression
+parameters and tables to a start-up state. The value of this code is 2**<code
+size>. For example if the code size indicated was 4 (image was 4 bits/pixel)
+the Clear code value would be 16 (10000 binary). The Clear code can appear at
+any point in the image data stream and therefore requires the LZW algorithm to
+process succeeding codes as if a new data stream was starting. Encoders should
+output a Clear code as the first code of each image data stream.
+
+2. An End of Information code is defined that explicitly indicates the end of
+the image data stream. LZW processing terminates when this code is encountered.
+It must be the last code output by the encoder for an image. The value of this
+code is <Clear code>+1.
+
+3. The first available compression code value is <Clear code>+2.
+
+4. The output codes are of variable length, starting at <code size>+1 bits per
+code, up to 12 bits per code. This defines a maximum code value of 4095
+(0xFFF). Whenever the LZW code value would exceed the current code length, the
+code length is increased by one. The packing/unpacking of these codes must then
+be altered to reflect the new code length.
+
+BUILD 8-BIT BYTES
+
+Because the LZW compression used for GIF creates a series of variable length
+codes, of between 3 and 12 bits each, these codes must be reformed into a
+series of 8-bit bytes that will be the characters actually stored or
+transmitted. This provides additional compression of the image. The codes are
+formed into a stream of bits as if they were packed right to left and then
+
+
+
+
+
+
+
+ 32
+
+
+picked off 8 bits at a time to be output.
+
+Assuming a character array of 8 bits per character and using 5 bit codes to be
+packed, an example layout would be similar to:
+
+
+ +---------------+
+ 0 | | bbbaaaaa
+ +---------------+
+ 1 | | dcccccbb
+ +---------------+
+ 2 | | eeeedddd
+ +---------------+
+ 3 | | ggfffffe
+ +---------------+
+ 4 | | hhhhhggg
+ +---------------+
+ . . .
+ +---------------+
+ N | |
+ +---------------+
+
+
+Note that the physical packing arrangement will change as the number of bits
+per compression code change but the concept remains the same.
+
+PACKAGE THE BYTES
+
+Once the bytes have been created, they are grouped into blocks for output by
+preceding each block of 0 to 255 bytes with a character count byte. A block
+with a zero byte count terminates the Raster Data stream for a given image.
+These blocks are what are actually output for the GIF image. This block format
+has the side effect of allowing a decoding program the ability to read past the
+actual image data if necessary by reading block counts and then skipping over
+the data.
+
+
+
+FURTHER READING
+
+[1] Ziv, J. and Lempel, A. : "A Universal Algorithm for Sequential Data
+Compression", IEEE Transactions on Information Theory, May 1977.
+[2] Welch, T. : "A Technique for High-Performance Data Compression", Computer,
+June 1984.
+[3] Nelson, M.R. : "LZW Data Compression", Dr. Dobb's Journal, October 1989.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 33
+
+
+Appendix
+G. On-line Capabilities Dialogue.
+
+NOTE : This section is currently (10 July 1990) under revision; the information
+provided here should be used as general guidelines. Code written based on this
+information should be designed in a flexible way to accommodate any changes
+resulting from the revisions.
+
+The following sequences are defined for use in mediating control between a GIF
+sender and GIF receiver over an interactive communications line. These
+sequences do not apply to applications that involve downloading of static GIF
+files and are not considered part of a GIF file.
+
+GIF CAPABILITIES ENQUIRY
+
+The GIF Capabilities Enquiry sequence is issued from a host and requests an
+interactive GIF decoder to return a response message that defines the graphics
+parameters for the decoder. This involves returning information about available
+screen sizes, number of bits/color supported and the amount of color detail
+supported. The escape sequence for the GIF Capabilities Enquiry is defined as:
+
+ESC[>0g 0x1B 0x5B 0x3E 0x30 0x67
+
+GIF CAPABILITIES RESPONSE
+
+The GIF Capabilities Response message is returned by an interactive GIF decoder
+and defines the decoder's display capabilities for all graphics modes that are
+supported by the software. Note that this can also include graphics printers as
+well as a monitor screen. The general format of this message is:
+
+#version;protocol{;dev, width, height, color-bits, color-res}...<CR>
+
+
+'#' GIF Capabilities Response identifier character.
+version GIF format version number; initially '87a'.
+protocol='0' No end-to-end protocol supported by decoder Transfer as direct
+ 8-bit data stream.
+protocol='1' Can use CIS B+ error correction protocol to transfer GIF data
+ interactively from the host directly to the display.
+dev = '0' Screen parameter set follows.
+dev = '1' Printer parameter set follows.
+width Maximum supported display width in pixels.
+height Maximum supported display height in pixels.
+color-bits Number of bits per pixel supported. The number of supported
+ colors is therefore 2**color-bits.
+color-res Number of bits per color component supported in the hardware
+ color palette. If color-res is '0' then no hardware palette
+ table is available.
+
+Note that all values in the GIF Capabilities Response are returned as ASCII
+decimal numbers and the message is terminated by a Carriage Return character.
+
+The following GIF Capabilities Response message describes three standard IBM PC
+Enhanced Graphics Adapter configurations with no printer; the GIF data stream
+
+
+
+
+
+
+
+
+
+ 34
+
+
+can be processed within an error correcting protocol:
+
+#87a;1;0,320,200,4,0;0,640,200,2,2;0,640,350,4,2<CR>
+
+ENTER GIF GRAPHICS MODE
+
+Two sequences are currently defined to invoke an interactive GIF decoder into
+action. The only difference between them is that different output media are
+selected. These sequences are:
+
+ESC[>1g Display GIF image on screen
+
+ 0x1B 0x5B 0x3E 0x31 0x67
+
+ESC[>2g Display image directly to an attached graphics printer. The image may
+optionally be displayed on the screen as well.
+
+ 0x1B 0x5B 0x3E 0x32 0x67
+
+Note that the 'g' character terminating each sequence is in lowercase.
+
+INTERACTIVE ENVIRONMENT
+
+The assumed environment for the transmission of GIF image data from an
+interactive application is a full 8-bit data stream from host to micro. All
+256 character codes must be transferrable. The establishing of an 8-bit data
+path for communications will normally be taken care of by the host application
+programs. It is however up to the receiving communications programs supporting
+GIF to be able to receive and pass on all 256 8-bit codes to the GIF decoder
+software.
+.
i_color fg, bg;
i_fcolor ffg, fbg;
unsigned char hatch[8];
- int dx, dy;
+ i_img_dim dx, dy;
} i_fill_hatch_t;
static void fill_hatch(i_fill_t *fill, i_img_dim x, i_img_dim y,
i_fill_t *
i_new_hatch_low(const i_color *fg, const i_color *bg, const i_fcolor *ffg, const i_fcolor *fbg,
int combine, int hatch, const unsigned char *cust_hatch,
- int dx, int dy);
+ i_img_dim dx, i_img_dim dy);
/*
=item i_new_fill_hatch(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
*/
i_fill_t *
i_new_fill_hatch(const i_color *fg, const i_color *bg, int combine, int hatch,
- const unsigned char *cust_hatch, int dx, int dy) {
+ const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) {
return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch,
dx, dy);
}
*/
i_fill_t *
i_new_fill_hatchf(const i_fcolor *fg, const i_fcolor *bg, int combine, int hatch,
- const unsigned char *cust_hatch, int dx, int dy) {
+ const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) {
return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch,
dx, dy);
}
struct i_fill_image_t {
i_fill_t base;
i_img *src;
- int xoff, yoff;
+ i_img_dim xoff, yoff;
int has_matrix;
double matrix[9];
};
=cut
*/
i_fill_t *
-i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combine) {
+i_new_fill_image(i_img *im, const double *matrix, i_img_dim xoff, i_img_dim yoff, int combine) {
struct i_fill_image_t *fill = mymalloc(sizeof(*fill)); /* checked 14jul05 tonyc */
*fill = image_fill_proto;
static struct i_fill_opacity_t
opacity_fill_proto =
{
- fill_opacity,
- fill_opacityf,
- NULL
+ {
+ fill_opacity,
+ fill_opacityf,
+ NULL
+ }
};
i_fill_t *
i_new_hatch_low(const i_color *fg, const i_color *bg,
const i_fcolor *ffg, const i_fcolor *fbg,
int combine, int hatch, const unsigned char *cust_hatch,
- int dx, int dy) {
+ i_img_dim dx, i_img_dim dy) {
i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t)); /* checked 14jul05 tonyc */
*fill = hatch_fill_proto;
int mask = 128 >> xpos;
i_color fg = f->fg;
i_color bg = f->bg;
- int want_channels = channels > 2 ? 4 : 2;
if (channels < 3) {
i_adapt_colors(2, 4, &fg, 1);
ry -= iy * f->src->ysize;
for (dy = 0; dy < 2; ++dy) {
- if ((int)rx == f->src->xsize-1) {
- i_gpix(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]);
- i_gpix(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]);
+ if ((i_img_dim)rx == f->src->xsize-1) {
+ i_gpix(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]);
+ i_gpix(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]);
}
else {
- i_glin(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize,
+ i_glin(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize,
c[dy]);
}
c2[dy] = interp_i_color(c[dy][0], c[dy][1], rx, f->src->channels);
ry -= iy * f->src->ysize;
for (dy = 0; dy < 2; ++dy) {
- if ((int)rx == f->src->xsize-1) {
- i_gpixf(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]);
- i_gpixf(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]);
+ if ((i_img_dim)rx == f->src->xsize-1) {
+ i_gpixf(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]);
+ i_gpixf(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]);
}
else {
- i_glinf(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize,
+ i_glinf(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize,
c[dy]);
}
c2[dy] = interp_i_fcolor(c[dy][0], c[dy][1], rx, f->src->channels);
void
i_contrast(i_img *im, float intensity) {
- int x, y;
+ i_img_dim x, y;
unsigned char ch;
unsigned int new_color;
i_color rcolor;
static int
s_hardinvert_low(i_img *im, int all) {
- int x, y;
+ i_img_dim x, y;
int ch;
int invert_channels = all ? im->channels : i_img_color_channels(im);
/*
=item i_noise(im, amount, type)
-Inverts the pixel values by the amount specified.
+Adjusts the sample values randomly by the amount specified.
+
+If type is 0, adjust all channels in a pixel by the same (random)
+amount amount, if non-zero adjust each sample independently.
im - image object
amount - deviation in pixel values
void
i_noise(i_img *im, float amount, unsigned char type) {
- int x, y;
+ i_img_dim x, y;
unsigned char ch;
int new_color;
float damount = amount * 2;
}
}
-
-/*
-=item i_noise(im, amount, type)
-
-Inverts the pixel values by the amount specified.
-
- im - image object
- amount - deviation in pixel values
- type - noise individual for each channel if true
-
-=cut
-*/
-
-
-/*
-=item i_applyimage(im, add_im, mode)
-
-Apply's an image to another image
-
- im - target image
- add_im - image that is applied to target
- mode - what method is used in applying:
-
- 0 Normal
- 1 Multiply
- 2 Screen
- 3 Overlay
- 4 Soft Light
- 5 Hard Light
- 6 Color dodge
- 7 Color Burn
- 8 Darker
- 9 Lighter
- 10 Add
- 11 Subtract
- 12 Difference
- 13 Exclusion
-
-=cut
-*/
-
-void i_applyimage(i_img *im, i_img *add_im, unsigned char mode) {
- int x, y;
- int mx, my;
-
- mm_log((1, "i_applyimage(im %p, add_im %p, mode %d", im, add_im, mode));
-
- mx = (add_im->xsize <= im->xsize) ? add_im->xsize : add_im->xsize;
- my = (add_im->ysize <= im->ysize) ? add_im->ysize : add_im->ysize;
-
- for(x = 0; x < mx; x++) {
- for(y = 0; y < my; y++) {
- }
- }
-}
-
-
/*
=item i_bumpmap(im, bump, channel, light_x, light_y, st)
*/
void
-i_bumpmap(i_img *im, i_img *bump, int channel, int light_x, int light_y, int st) {
- int x, y, ch;
- int mx, my;
+i_bumpmap(i_img *im, i_img *bump, int channel, i_img_dim light_x, i_img_dim light_y, i_img_dim st) {
+ i_img_dim x, y;
+ int ch;
+ i_img_dim mx, my;
i_color x1_color, y1_color, x2_color, y2_color, dst_color;
double nX, nY;
double tX, tY, tZ;
i_img new_im;
- mm_log((1, "i_bumpmap(im %p, add_im %p, channel %d, light_x %d, light_y %d, st %d)\n",
- im, bump, channel, light_x, light_y, st));
+ mm_log((1, "i_bumpmap(im %p, add_im %p, channel %d, light(" i_DFp "), st %" i_DF ")\n",
+ im, bump, channel, i_DFcp(light_x, light_y), i_DFc(st)));
if(channel >= bump->channels) {
fZ = (sqrt((nX * nX) + (nY * nY)) / aL);
- tX = abs(x - light_x) / aL;
- tY = abs(y - light_y) / aL;
+ tX = i_abs(x - light_x) / aL;
+ tY = i_abs(y - light_y) / aL;
tZ = 1 - (sqrt((tX * tX) + (tY * tY)) * fZ);
}
}
- i_copyto(im, &new_im, 0, 0, (int)im->xsize, (int)im->ysize, 0, 0);
+ i_copyto(im, &new_im, 0, 0, im->xsize, im->ysize, 0, 0);
i_img_exorcise(&new_im);
}
typedef struct {
- float x,y,z;
+ double x,y,z;
} fvec;
i_bumpmap_complex(i_img *im,
i_img *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,
i_img new_im;
int inflight;
- int x, y, ch;
- int mx, Mx, my, My;
+ i_img_dim x, y;
+ int ch;
+ i_img_dim mx, Mx, my, My;
float cdc[MAXCHANNELS];
float csc[MAXCHANNELS];
fvec R; /* Reflection vector */
fvec V; /* Vision vector */
- mm_log((1, "i_bumpmap_complex(im %p, bump %p, channel %d, tx %d, ty %d, Lx %.2f, Ly %.2f, Lz %.2f, cd %.2f, cs %.2f, n %.2f, Ia %p, Il %p, Is %p)\n",
- im, bump, channel, tx, ty, Lx, Ly, Lz, cd, cs, n, Ia, Il, Is));
+ mm_log((1, "i_bumpmap_complex(im %p, bump %p, channel %d, t(" i_DFp
+ "), Lx %.2f, Ly %.2f, Lz %.2f, cd %.2f, cs %.2f, n %.2f, Ia %p, Il %p, Is %p)\n",
+ im, bump, channel, i_DFcp(tx, ty), Lx, Ly, Lz, cd, cs, n, Ia, Il, Is));
if (channel >= bump->channels) {
mm_log((1, "i_bumpmap_complex: channel = %d while bump image only has %d channels\n", channel, bump->channels));
}
}
- i_copyto(im, &new_im, 0, 0, (int)im->xsize, (int)im->ysize, 0, 0);
+ i_copyto(im, &new_im, 0, 0, im->xsize, im->ysize, 0, 0);
i_img_exorcise(&new_im);
}
void
i_postlevels(i_img *im, int levels) {
- int x, y, ch;
+ i_img_dim x, y;
+ int ch;
float pv;
int rv;
float av;
*/
void
-i_mosaic(i_img *im, int size) {
- int x, y, ch;
- int lx, ly, z;
+i_mosaic(i_img *im, i_img_dim size) {
+ i_img_dim x, y;
+ int ch, z;
+ i_img_dim lx, ly;
long sqrsize;
i_color rcolor;
*/
void
-i_watermark(i_img *im, i_img *wmark, int tx, int ty, int pixdiff) {
- int vx, vy, ch;
+i_watermark(i_img *im, i_img *wmark, i_img_dim tx, i_img_dim ty, int pixdiff) {
+ i_img_dim vx, vy;
+ int ch;
i_color val, wval;
- int mx = wmark->xsize;
- int my = wmark->ysize;
+ i_img_dim mx = wmark->xsize;
+ i_img_dim my = wmark->ysize;
for(vx=0;vx<mx;vx++) for(vy=0;vy<my;vy++) {
void
i_autolevels(i_img *im, float lsat, float usat, float skew) {
i_color val;
- int i, x, y, rhist[256], ghist[256], bhist[256];
- int rsum, rmin, rmax;
- int gsum, gmin, gmax;
- int bsum, bmin, bmax;
- int rcl, rcu, gcl, gcu, bcl, bcu;
+ i_img_dim i, x, y, rhist[256], ghist[256], bhist[256];
+ i_img_dim rsum, rmin, rmax;
+ i_img_dim gsum, gmin, gmax;
+ i_img_dim bsum, bmin, bmax;
+ i_img_dim rcl, rcu, gcl, gcu, bcl, bcu;
mm_log((1,"i_autolevels(im %p, lsat %f,usat %f,skew %f)\n", im, lsat,usat,skew));
*/
static
-float
-Noise(int x, int y) {
- int n = x + y * 57;
+double
+Noise(i_img_dim x, i_img_dim y) {
+ i_img_dim n = x + y * 57;
n = (n<<13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
*/
static
-float
-SmoothedNoise1(float x, float y) {
- float corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
- float sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
- float center = Noise(x, y) / 4;
+double
+SmoothedNoise1(double x, double y) {
+ double corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
+ double sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
+ double center = Noise(x, y) / 4;
return corners + sides + center;
}
*/
static
-float C_Interpolate(float a, float b, float x) {
+double
+C_Interpolate(double a, double b, double x) {
/* float ft = x * 3.1415927; */
- float ft = x * PI;
- float f = (1 - cos(ft)) * .5;
+ double ft = x * PI;
+ double f = (1 - cos(ft)) * .5;
return a*(1-f) + b*f;
}
*/
static
-float
-InterpolatedNoise(float x, float y) {
+double
+InterpolatedNoise(double x, double y) {
- int integer_X = x;
- float fractional_X = x - integer_X;
- int integer_Y = y;
- float fractional_Y = y - integer_Y;
+ i_img_dim integer_X = x;
+ double fractional_X = x - integer_X;
+ i_img_dim integer_Y = y;
+ double fractional_Y = y - integer_Y;
- float v1 = SmoothedNoise1(integer_X, integer_Y);
- float v2 = SmoothedNoise1(integer_X + 1, integer_Y);
- float v3 = SmoothedNoise1(integer_X, integer_Y + 1);
- float v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
+ double v1 = SmoothedNoise1(integer_X, integer_Y);
+ double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
+ double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
+ double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
- float i1 = C_Interpolate(v1 , v2 , fractional_X);
- float i2 = C_Interpolate(v3 , v4 , fractional_X);
+ double i1 = C_Interpolate(v1 , v2 , fractional_X);
+ double i2 = C_Interpolate(v3 , v4 , fractional_X);
return C_Interpolate(i1 , i2 , fractional_Y);
}
float
PerlinNoise_2D(float x, float y) {
int i,frequency;
- float amplitude;
- float total = 0;
+ double amplitude;
+ double total = 0;
int Number_Of_Octaves=6;
int n = Number_Of_Octaves - 1;
*/
void
-i_radnoise(i_img *im, int xo, int yo, float rscale, float ascale) {
- int x, y, ch;
+i_radnoise(i_img *im, i_img_dim xo, i_img_dim yo, double rscale, double ascale) {
+ i_img_dim x, y;
+ int ch;
i_color val;
unsigned char v;
- float xc, yc, r;
+ double xc, yc, r;
double a;
for(y = 0; y < im->ysize; y++) for(x = 0; x < im->xsize; x++) {
- xc = (float)x-xo+0.5;
- yc = (float)y-yo+0.5;
+ xc = (double)x-xo+0.5;
+ yc = (double)y-yo+0.5;
r = rscale*sqrt(xc*xc+yc*yc)+1.2;
a = (PI+atan2(yc,xc))*ascale;
v = saturate(128+100*(PerlinNoise_2D(a,r)));
*/
void
-i_turbnoise(i_img *im, float xo, float yo, float scale) {
- int x,y,ch;
+i_turbnoise(i_img *im, double xo, double yo, double scale) {
+ i_img_dim x,y;
+ int ch;
unsigned char v;
i_color val;
for(y = 0; y < im->ysize; y++) for(x = 0; x < im->xsize; x++) {
/* v=saturate(125*(1.0+PerlinNoise_2D(xo+(float)x/scale,yo+(float)y/scale))); */
- v = saturate(120*(1.0+sin(xo+(float)x/scale+PerlinNoise_2D(xo+(float)x/scale,yo+(float)y/scale))));
+ v = saturate(120*(1.0+sin(xo+(double)x/scale+PerlinNoise_2D(xo+(double)x/scale,yo+(float)y/scale))));
for(ch=0; ch<im->channels; ch++) val.channel[ch] = v;
i_ppix(im, x, y, &val);
}
void
-i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
+i_gradgen(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *ival, int dmeasure) {
i_color val;
- int p, x, y, ch;
+ int p, ch;
+ i_img_dim x, y;
int channels = im->channels;
- int xsize = im->xsize;
- int ysize = im->ysize;
- int bytes;
+ i_img_dim xsize = im->xsize;
+ i_img_dim ysize = im->ysize;
+ size_t bytes;
- float *fdist;
+ double *fdist;
mm_log((1,"i_gradgen(im %p, num %d, xo %p, yo %p, ival %p, dmeasure %d)\n", im, num, xo, yo, ival, dmeasure));
for(p = 0; p<num; p++) {
- mm_log((1,"i_gradgen: (%d, %d)\n", xo[p], yo[p]));
+ mm_log((1,"i_gradgen: p%d(" i_DFp ")\n", p, i_DFcp(xo[p], yo[p])));
ICL_info(&ival[p]);
}
overflow is a programming error rather than an end-user error, so
calling exit() is justified.
*/
- bytes = sizeof(float) * num;
- if (bytes / num != sizeof(float)) {
+ bytes = sizeof(double) * num;
+ if (bytes / num != sizeof(double)) {
fprintf(stderr, "integer overflow calculating memory allocation");
exit(1);
}
fdist = mymalloc( bytes ); /* checked 14jul05 tonyc */
for(y = 0; y<ysize; y++) for(x = 0; x<xsize; x++) {
- float cs = 0;
- float csd = 0;
+ double cs = 0;
+ double csd = 0;
for(p = 0; p<num; p++) {
- int xd = x-xo[p];
- int yd = y-yo[p];
+ i_img_dim xd = x-xo[p];
+ i_img_dim yd = y-yo[p];
switch (dmeasure) {
case 0: /* euclidean */
fdist[p] = sqrt(xd*xd + yd*yd); /* euclidean distance */
}
void
-i_nearest_color_foo(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure) {
+i_nearest_color_foo(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *ival, int dmeasure) {
- int p, x, y;
- int xsize = im->xsize;
- int ysize = im->ysize;
+ int p;
+ i_img_dim x, y;
+ i_img_dim xsize = im->xsize;
+ i_img_dim ysize = im->ysize;
mm_log((1,"i_gradgen(im %p, num %d, xo %p, yo %p, ival %p, dmeasure %d)\n", im, num, xo, yo, ival, dmeasure));
for(p = 0; p<num; p++) {
- mm_log((1,"i_gradgen: (%d, %d)\n", xo[p], yo[p]));
+ mm_log((1,"i_gradgen: p%d(" i_DFp ")\n", p, i_DFcp(xo[p], yo[p])));
ICL_info(&ival[p]);
}
for(y = 0; y<ysize; y++) for(x = 0; x<xsize; x++) {
- int midx = 0;
- float mindist = 0;
- float curdist = 0;
+ int midx = 0;
+ double mindist = 0;
+ double curdist = 0;
- int xd = x-xo[0];
- int yd = y-yo[0];
+ i_img_dim xd = x-xo[0];
+ i_img_dim yd = y-yo[0];
switch (dmeasure) {
case 0: /* euclidean */
=item *
-int *xo - array of I<num> x positions
+i_img_dim *xo - array of I<num> x positions
=item *
-int *yo - array of I<num> y positions
+i_img_dim *yo - array of I<num> y positions
=item *
*/
int
-i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *oval, int dmeasure) {
+i_nearest_color(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *oval, int dmeasure) {
i_color *ival;
float *tval;
- float c1, c2;
+ double c1, c2;
i_color val;
- int p, x, y, ch;
- int xsize = im->xsize;
- int ysize = im->ysize;
+ int p, ch;
+ i_img_dim x, y;
+ i_img_dim xsize = im->xsize;
+ i_img_dim ysize = im->ysize;
int *cmatch;
- int ival_bytes, tval_bytes;
+ size_t ival_bytes, tval_bytes;
mm_log((1,"i_nearest_color(im %p, num %d, xo %p, yo %p, oval %p, dmeasure %d)\n", im, num, xo, yo, oval, dmeasure));
for(y = 0; y<ysize; y++) for(x = 0; x<xsize; x++) {
int midx = 0;
- float mindist = 0;
- float curdist = 0;
+ double mindist = 0;
+ double curdist = 0;
- int xd = x-xo[0];
- int yd = y-yo[0];
+ i_img_dim xd = x-xo[0];
+ i_img_dim yd = y-yo[0];
switch (dmeasure) {
case 0: /* euclidean */
}
- for(p = 0; p<num; p++) for(ch = 0; ch<im->channels; ch++)
- ival[p].channel[ch] = tval[p*im->channels + ch];
+ for(p = 0; p<num; p++) {
+ for(ch = 0; ch<im->channels; ch++)
+ ival[p].channel[ch] = tval[p*im->channels + ch];
+
+ /* avoid uninitialized value messages from valgrind */
+ while (ch < MAXCHANNELS)
+ ival[p].channel[ch++] = 0;
+ }
i_nearest_color_foo(im, num, xo, yo, ival, dmeasure);
void
i_unsharp_mask(i_img *im, double stddev, double scale) {
i_img *copy;
- int x, y, ch;
+ i_img_dim x, y;
+ int ch;
if (scale < 0)
return;
i_diff_image(i_img *im1, i_img *im2, double mindist) {
i_img *out;
int outchans, diffchans;
- int xsize, ysize;
+ i_img_dim xsize, ysize;
i_clear_error();
if (im1->channels != im2->channels) {
i_color *line1 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
i_color *line2 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
i_color empty;
- int x, y, ch;
+ i_img_dim x, y;
+ int ch;
int imindist = (int)mindist;
for (ch = 0; ch < MAXCHANNELS; ++ch)
i_fcolor *line1 = mymalloc(xsize * sizeof(*line1)); /* checked 17feb2005 tonyc */
i_fcolor *line2 = mymalloc(xsize * sizeof(*line2)); /* checked 17feb2005 tonyc */
i_fcolor empty;
- int x, y, ch;
+ i_img_dim x, y;
+ int ch;
double dist = mindist / 255.0;
for (ch = 0; ch < MAXCHANNELS; ++ch)
double cos;
double sin;
double theta;
- int xa, ya;
+ i_img_dim xa, ya;
void *ssample_data;
fount_func ffunc;
fount_repeat rpfunc;
int combine, int super_sample, double ssample_param,
int count, i_fountain_seg *segs) {
struct fount_state state;
- int x, y;
+ i_img_dim x, y;
i_fcolor *line = NULL;
i_fcolor *work = NULL;
- int line_bytes;
+ size_t line_bytes;
i_fountain_seg *my_segs;
i_fill_combine_f combine_func = NULL;
i_fill_combinef_f combinef_func = NULL;
i_fountain_repeat repeat, int combine, int super_sample,
double ssample_param, int count, i_fountain_seg *segs) {
int i, j;
- int bytes;
+ size_t bytes;
i_fountain_seg *my_segs = mymalloc(sizeof(i_fountain_seg) * count); /* checked 2jul06 - duplicating original */
/*int have_alpha = im->channels == 2 || im->channels == 4;*/
*/
static double
square_fount_f(double x, double y, struct fount_state *state) {
- int xc, yc; /* centred on A */
+ i_img_dim xc, yc; /* centred on A */
double xt, yt; /* rotated by theta */
xc = x - state->xa;
yc = y - state->ya;
static int
simple_ssample(i_fcolor *out, double x, double y, struct fount_state *state) {
i_fcolor *work = state->ssample_data;
- int dx, dy;
+ i_img_dim dx, dy;
int grid = state->parm;
double base = -0.5 + 0.5 / grid;
double step = 1.0 / grid;
static void
flip_h(i_img *im) {
- int y;
+ i_img_dim y;
if (im->type == i_palette_type) {
i_palidx *line = mymalloc(im->xsize * sizeof(i_palidx));
for (y = 0; y < im->ysize; ++y) {
static void
flip_v(i_img *im) {
- int topy = 0;
- int boty = im->ysize - 1;
+ i_img_dim topy = 0;
+ i_img_dim boty = im->ysize - 1;
if (im->type == i_palette_type) {
i_palidx *top_line = mymalloc(im->xsize * sizeof(i_palidx));
i_palidx *bot_line = mymalloc(im->xsize * sizeof(i_palidx));
static void
flip_hv(i_img *im) {
- int topy = 0;
- int boty = im->ysize - 1;
+ i_img_dim topy = 0;
+ i_img_dim boty = im->ysize - 1;
if (im->type == i_palette_type) {
i_palidx *top_line = mymalloc(im->xsize * sizeof(i_palidx));
i_palidx *bot_line = mymalloc(im->xsize * sizeof(i_palidx));
#ifdef HAVE_LIBT1
fontnum = i_t1_new(path_to_pfb, path_to_afm);
- i_t1_bbox(fontnum, points, "foo", 3, int cords[6]);
+ i_t1_bbox(fontnum, points, "foo", 3, i_img_dim cords[BOUNDING_BOX_COUNT]);
rc = i_t1_destroy(fontnum);
#endif
TT_Glyph_Metrics gmetrics[256];
i_tt_glyph_entry glyphs[256];
int smooth;
- int ptsize;
int order;
+ i_img_dim ptsize;
};
typedef struct TT_Instancehandle_ TT_Instancehandle;
/* Prototypes */
-static int i_tt_get_instance( TT_Fonthandle *handle, int points, int smooth );
-static void i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth );
+static int i_tt_get_instance( TT_Fonthandle *handle, i_img_dim points, int smooth );
+static void i_tt_init_raster_map( TT_Raster_Map* bit, i_img_dim width, i_img_dim height, int smooth );
static void i_tt_done_raster_map( TT_Raster_Map *bit );
static void i_tt_clear_raster_map( TT_Raster_Map* bit );
-static void i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off );
+static void i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,i_img_dim x_off, i_img_dim y_off );
static int i_tt_get_glyph( TT_Fonthandle *handle, int inst, unsigned long j );
static void
i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics,
TT_Raster_Map *bit, TT_Raster_Map *small_bit,
- int x_off, int y_off, int smooth );
+ i_img_dim x_off, i_img_dim y_off, int smooth );
static int
i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit,
- TT_Raster_Map *small_bit, int cords[6],
+ TT_Raster_Map *small_bit, i_img_dim cords[6],
char const* txt, size_t len, int smooth, int utf8 );
-static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth );
-static void i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, int xb, int yb, int channel, int smooth );
+static void i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, const i_color *cl, int smooth );
+static void i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, int channel, int smooth );
static int
-i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6],
- float points, char const* txt, size_t len, int smooth, int utf8 );
-static undef_int i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, int cords[6], int utf8 );
+i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, i_img_dim cords[6],
+ double points, char const* txt, size_t len, int smooth, int utf8 );
+static undef_int i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim cords[6], int utf8 );
/* static globals needed */
mm_log((1,"init_tt()\n"));
error = TT_Init_FreeType( &engine );
if ( error ){
- mm_log((1,"Initialization of freetype failed, code = 0x%x\n",error));
+ mm_log((1,"Initialization of freetype failed, code = 0x%x\n",
+ (unsigned)error));
i_tt_push_error(error);
i_push_error(0, "Could not initialize freetype 1.x");
return(1);
#ifdef FTXPOST
error = TT_Init_Post_Extension( engine );
if (error) {
- mm_log((1, "Initialization of Post extension failed = 0x%x\n", error));
+ mm_log((1, "Initialization of Post extension failed = 0x%x\n",
+ (unsigned)error));
i_tt_push_error(error);
i_push_error(0, "Could not initialize FT 1.x POST extension");
error = TT_Set_Raster_Gray_Palette(engine, palette);
if (error) {
- mm_log((1, "Initialization of gray levels failed = 0x%x\n", error));
+ mm_log((1, "Initialization of gray levels failed = 0x%x\n",
+ (unsigned)error));
i_tt_push_error(error);
i_push_error(0, "Could not initialize FT 1.x POST extension");
return 1;
static
int
-i_tt_get_instance( TT_Fonthandle *handle, int points, int smooth ) {
+i_tt_get_instance( TT_Fonthandle *handle, i_img_dim points, int smooth ) {
int i,idx;
TT_Error error;
- mm_log((1,"i_tt_get_instance(handle 0x%X, points %d, smooth %d)\n",
- handle,points,smooth));
+ mm_log((1,"i_tt_get_instance(handle %p, points %" i_DF ", smooth %d)\n",
+ handle, i_DFc(points), smooth));
if (smooth == -1) { /* Smooth doesn't matter for this search */
for(i=0;i<TT_CHC;i++) {
}
mm_log((1,"i_tt_get_instance: lru item is %d\n",idx));
- mm_log((1,"i_tt_get_instance: lru pointer 0x%X\n",
+ mm_log((1,"i_tt_get_instance: lru pointer %p\n",
USTRCT(handle->instanceh[idx].instance) ));
if ( USTRCT(handle->instanceh[idx].instance) ) {
( error = TT_Set_Instance_CharSize( handle->instanceh[idx].instance, points*64 ) ) );
if ( error ) {
- mm_log((1, "Could not create and initialize instance: error 0x%x.\n",error ));
+ mm_log((1, "Could not create and initialize instance: error %x.\n",
+ (unsigned)error ));
return -1;
}
}
else {
mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname,
- error ));
+ (unsigned)error ));
}
i_tt_push_error(error);
return NULL;
handle->loaded_names = 0;
#endif
- mm_log((1,"i_tt_new <- 0x%X\n",handle));
+ mm_log((1,"i_tt_new <- %p\n",handle));
return handle;
}
static
void
-i_tt_init_raster_map( TT_Raster_Map* bit, int width, int height, int smooth ) {
+i_tt_init_raster_map( TT_Raster_Map* bit, i_img_dim width, i_img_dim height, int smooth ) {
- mm_log((1,"i_tt_init_raster_map( bit 08x%08X, width %d, height %d, smooth %d)\n", bit, width, height, smooth));
+ mm_log((1,"i_tt_init_raster_map( bit %p, width %" i_DF ", height %" i_DF
+ ", smooth %d)\n", bit, i_DFc(width), i_DFc(height), smooth));
bit->rows = height;
bit->width = ( width + 3 ) & -4;
bit->width, bit->rows);
}
- mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %d)\n", bit->width, bit->cols, bit->rows, bit->size ));
+ mm_log((1,"i_tt_init_raster_map: bit->width %d, bit->cols %d, bit->rows %d, bit->size %ld)\n", bit->width, bit->cols, bit->rows, bit->size ));
bit->bitmap = (void *) mymalloc( bit->size ); /* checked 6Nov05 tonyc */
if ( !bit->bitmap ) i_fatal(0,"Not enough memory to allocate bitmap (%d)!\n",bit->size );
static
void
-i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,int x_off, int y_off ) {
- int x, y;
- int x1, x2, y1, y2;
+i_tt_blit_or( TT_Raster_Map *dst, TT_Raster_Map *src,i_img_dim x_off, i_img_dim y_off ) {
+ i_img_dim x, y;
+ i_img_dim x1, x2, y1, y2;
unsigned char *s, *d;
x1 = x_off < 0 ? -x_off : 0;
unsigned short load_flags, code;
TT_Error error;
- mm_log((1, "i_tt_get_glyph(handle 0x%X, inst %d, j %d (%c))\n",
- handle,inst,j, ((j >= ' ' && j <= '~') ? j : '.')));
+ mm_log((1, "i_tt_get_glyph(handle %p, inst %d, j %lu (%c))\n",
+ handle,inst,j, (int)((j >= ' ' && j <= '~') ? j : '.')));
/*mm_log((1, "handle->instanceh[inst].glyphs[j]=0x%08X\n",handle->instanceh[inst].glyphs[j] ));*/
if ( TT_VALID(handle->instanceh[inst].glyphs[TT_HASH(j)].glyph)
&& handle->instanceh[inst].glyphs[TT_HASH(j)].ch == j) {
- mm_log((1,"i_tt_get_glyph: %d in cache\n",j));
+ mm_log((1,"i_tt_get_glyph: %lu in cache\n",j));
return 1;
}
} else code = TT_Char_Index( handle->char_map, j );
if ( (error = TT_New_Glyph( handle->face, &handle->instanceh[inst].glyphs[TT_HASH(j)].glyph)) ) {
- mm_log((1, "Cannot allocate and load glyph: error 0x%x.\n", error ));
+ mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error ));
i_push_error(error, "TT_New_Glyph()");
return 0;
}
if ( (error = TT_Load_Glyph( handle->instanceh[inst].instance, handle->instanceh[inst].glyphs[TT_HASH(j)].glyph, code, load_flags)) ) {
- mm_log((1, "Cannot allocate and load glyph: error 0x%x.\n", error ));
+ mm_log((1, "Cannot allocate and load glyph: error %#x.\n", (unsigned)error ));
/* Don't leak */
TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph );
USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL;
error = TT_Get_Glyph_Metrics( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph,
&handle->instanceh[inst].gmetrics[TT_HASH(j)] );
if (error) {
- mm_log((1, "TT_Get_Glyph_Metrics: error 0x%x.\n", error ));
+ mm_log((1, "TT_Get_Glyph_Metrics: error %#x.\n", (unsigned)error ));
TT_Done_Glyph( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph );
USTRCT( handle->instanceh[inst].glyphs[TT_HASH(j)].glyph ) = NULL;
handle->instanceh[inst].glyphs[TT_HASH(j)].ch = TT_NOCHAR;
=cut
*/
-int
+size_t
i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8,
char *out) {
- int count = 0;
- mm_log((1, "i_tt_has_chars(handle %p, text %p, len %d, utf8 %d)\n",
- handle, text, len, utf8));
+ size_t count = 0;
+ mm_log((1, "i_tt_has_chars(handle %p, text %p, len %ld, utf8 %d)\n",
+ handle, text, (long)len, utf8));
while (len) {
unsigned long c;
static
void
-i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bit, TT_Raster_Map *small_bit, int x_off, int y_off, int smooth ) {
+i_tt_render_glyph( TT_Glyph glyph, TT_Glyph_Metrics* gmetrics, TT_Raster_Map *bit, TT_Raster_Map *small_bit, i_img_dim x_off, i_img_dim y_off, int smooth ) {
- mm_log((1,"i_tt_render_glyph(glyph 0x0%X, gmetrics 0x0%X, bit 0x%X, small_bit 0x%X, x_off %d, y_off %d, smooth %d)\n",
- USTRCT(glyph), gmetrics, bit, small_bit, x_off,y_off,smooth));
+ mm_log((1,"i_tt_render_glyph(glyph %p, gmetrics %p, bit %p, small_bit %p, x_off %" i_DF ", y_off %" i_DF ", smooth %d)\n",
+ USTRCT(glyph), gmetrics, bit, small_bit, i_DFc(x_off),
+ i_DFc(y_off), smooth));
if ( !smooth ) TT_Get_Glyph_Bitmap( glyph, bit, x_off * 64, y_off * 64);
else {
static
int
i_tt_render_all_glyphs( TT_Fonthandle *handle, int inst, TT_Raster_Map *bit,
- TT_Raster_Map *small_bit, int cords[6],
+ TT_Raster_Map *small_bit, i_img_dim cords[6],
char const* txt, size_t len, int smooth, int utf8 ) {
unsigned long j;
TT_F26Dot6 x,y;
- mm_log((1,"i_tt_render_all_glyphs( handle 0x%X, inst %d, bit 0x%X, small_bit 0x%X, txt '%.*s', len %d, smooth %d, utf8 %d)\n",
- handle, inst, bit, small_bit, len, txt, len, smooth, utf8));
+ mm_log((1,"i_tt_render_all_glyphs( handle %p, inst %d, bit %p, small_bit %p, txt '%.*s', len %ld, smooth %d, utf8 %d)\n",
+ handle, inst, bit, small_bit, (int)len, txt, (long)len, smooth, utf8));
/*
y=-( handle->properties.horizontal->Descender * handle->instanceh[inst].imetrics.y_ppem )/(handle->properties.header->Units_Per_EM);
static
void
-i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, int xb, int yb, const i_color *cl, int smooth ) {
+i_tt_dump_raster_map2( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, const i_color *cl, int smooth ) {
unsigned char *bmap;
- int x, y;
- mm_log((1,"i_tt_dump_raster_map2(im 0x%x, bit 0x%X, xb %d, yb %d, cl 0x%X)\n",im,bit,xb,yb,cl));
+ i_img_dim x, y;
+ mm_log((1,"i_tt_dump_raster_map2(im %p, bit %p, xb %" i_DF ", yb %" i_DF ", cl %p)\n",
+ im, bit, i_DFc(xb), i_DFc(yb), cl));
bmap = bit->bitmap;
i_render r;
i_render_init(&r, im, bit->cols);
for(y=0;y<bit->rows;y++) {
-#if 0
- for(x=0;x<bit->width;x++) {
- c = (unsigned char)bmap[y*(bit->cols)+x];
- i=255-c;
- i_gpix(im,x+xb,y+yb,&val);
- for(ch=0;ch<im->channels;ch++)
- val.channel[ch] = (c*cl->channel[ch]+i*val.channel[ch])/255;
- i_ppix(im,x+xb,y+yb,&val);
- }
-#else
i_render_color(&r, xb, yb+y, bit->cols, bmap + y*bit->cols, cl);
-#endif
}
i_render_done(&r);
} else {
static
void
-i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, int xb, int yb, int channel, int smooth ) {
+i_tt_dump_raster_map_channel( i_img* im, TT_Raster_Map* bit, i_img_dim xb, i_img_dim yb, int channel, int smooth ) {
unsigned char *bmap;
i_color val;
- int c,x,y;
+ int c;
+ i_img_dim x,y;
int old_mask = im->ch_mask;
im->ch_mask = 1 << channel;
- mm_log((1,"i_tt_dump_raster_channel(im 0x%x, bit 0x%X, xb %d, yb %d, channel %d)\n",im,bit,xb,yb,channel));
+ mm_log((1,"i_tt_dump_raster_channel(im %p, bit %p, xb %" i_DF ", yb %" i_DF ", channel %d)\n",
+ im, bit, i_DFc(xb), i_DFc(yb), channel));
bmap = bit->bitmap;
static
int
-i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, int cords[6], float points, char const* txt, size_t len, int smooth, int utf8 ) {
+i_tt_rasterize( TT_Fonthandle *handle, TT_Raster_Map *bit, i_img_dim cords[6], double points, char const* txt, size_t len, int smooth, int utf8 ) {
int inst;
- int width, height;
+ i_img_dim width, height;
TT_Raster_Map small_bit;
/* find or install an instance */
width = cords[2]-cords[0];
height = cords[5]-cords[4];
- mm_log((1,"i_tt_rasterize: width=%d, height=%d\n",width, height ));
+ mm_log((1,"i_tt_rasterize: width=%" i_DF ", height=%" i_DF "\n",
+ i_DFc(width), i_DFc(height) ));
i_tt_init_raster_map ( bit, width, height, smooth );
i_tt_clear_raster_map( bit );
*/
undef_int
-i_tt_cp( TT_Fonthandle *handle, i_img *im, int xb, int yb, int channel, float points, char const* txt, size_t len, int smooth, int utf8, int align ) {
+i_tt_cp( TT_Fonthandle *handle, i_img *im, i_img_dim xb, i_img_dim yb, int channel, double points, char const* txt, size_t len, int smooth, int utf8, int align ) {
- int cords[BOUNDING_BOX_COUNT];
- int ascent, st_offset, y;
+ i_img_dim cords[BOUNDING_BOX_COUNT];
+ i_img_dim ascent, st_offset, y;
TT_Raster_Map bit;
i_clear_error();
*/
undef_int
-i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, const i_color *cl, float points, char const* txt, size_t len, int smooth, int utf8, int align) {
- int cords[BOUNDING_BOX_COUNT];
- int ascent, st_offset, y;
+i_tt_text( TT_Fonthandle *handle, i_img *im, i_img_dim xb, i_img_dim yb, const i_color *cl, double points, char const* txt, size_t len, int smooth, int utf8, int align) {
+ i_img_dim cords[BOUNDING_BOX_COUNT];
+ i_img_dim ascent, st_offset, y;
TT_Raster_Map bit;
i_clear_error();
static
undef_int
-i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, int cords[BOUNDING_BOX_COUNT], int utf8 ) {
+i_tt_bbox_inst( TT_Fonthandle *handle, int inst ,const char *txt, size_t len, i_img_dim cords[BOUNDING_BOX_COUNT], int utf8 ) {
int upm, casc, cdesc, first;
int start = 0;
- int width = 0;
+ i_img_dim width = 0;
int gdescent = 0;
int gascent = 0;
int descent = 0;
unsigned char *ustr;
ustr=(unsigned char*)txt;
- mm_log((1,"i_tt_box_inst(handle 0x%X,inst %d,txt '%.*s', len %d, utf8 %d)\n",handle,inst,len,txt,len, utf8));
+ mm_log((1,"i_tt_box_inst(handle %p,inst %d,txt '%.*s', len %ld, utf8 %d)\n",
+ handle, inst, (int)len, txt, (long)len, utf8));
upm = handle->properties.header->Units_Per_EM;
gascent = ( handle->properties.horizontal->Ascender * handle->instanceh[inst].imetrics.y_ppem + upm - 1) / upm;
cdesc = (gm->bbox.yMin-63) / 64;
mm_log((1, "i_tt_box_inst: glyph='%c' casc=%d cdesc=%d\n",
- ((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc));
+ (int)((j >= ' ' && j <= '~') ? j : '.'), casc, cdesc));
if (first) {
start = gm->bbox.xMin / 64;
*/
undef_int
-i_tt_bbox( TT_Fonthandle *handle, float points,const char *txt,size_t len,int cords[6], int utf8) {
+i_tt_bbox( TT_Fonthandle *handle, double points,const char *txt,size_t len,i_img_dim cords[6], int utf8) {
int inst;
i_clear_error();
- mm_log((1,"i_tt_box(handle 0x%X,points %f,txt '%.*s', len %d, utf8 %d)\n",handle,points,len,txt,len, utf8));
+ mm_log((1,"i_tt_box(handle %p,points %f,txt '%.*s', len %ld, utf8 %d)\n",
+ handle, points, (int)len, txt, (long)len, utf8));
if ( (inst=i_tt_get_instance(handle,points,-1)) < 0) {
i_push_errorf(0, "i_tt_get_instance(%g)", points);
=cut
*/
-int
+size_t
i_tt_face_name(TT_Fonthandle *handle, char *name_buf, size_t name_buf_size) {
TT_Face_Properties props;
int name_count;
fflush(stdout);
}
-int
+size_t
i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf,
size_t name_buf_size) {
#ifdef FTXPOST
}
if (handle->load_cond) {
- i_push_errorf(handle->load_cond, "error loading names (%d)", handle->load_cond);
+ i_push_errorf(handle->load_cond, "error loading names (%#x)",
+ (unsigned)handle->load_cond);
return 0;
}
static double
gauss(int x, double std) {
- return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(float)(x)/(2*std*std));
+ return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(double)(x)/(2*std*std));
}
/* Counters are as follows
int
i_gaussian(i_img *im, double stddev) {
- int i,l,c,ch;
+ int i, c, ch;
+ i_img_dim x, y;
double pc;
double *coeff;
double res[MAXCHANNELS];
#code im->bits <= 8
IM_COLOR rcolor;
- for(l=0;l<im->ysize;l++) {
- for(i=0;i<im->xsize;i++) {
+ for(y = 0; y < im->ysize; y++) {
+ for(x = 0; x < im->xsize; x++) {
pc=0.0;
for(ch=0;ch<im->channels;ch++)
res[ch]=0;
for(c = 0;c < diameter; c++)
- if (IM_GPIX(im,i+c-radius,l,&rcolor)!=-1) {
+ if (IM_GPIX(im,x+c-radius,y,&rcolor)!=-1) {
for(ch=0;ch<im->channels;ch++)
res[ch]+= rcolor.channel[ch] * coeff[c];
pc+=coeff[c];
double value = res[ch] / pc;
rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
}
- IM_PPIX(timg,i,l,&rcolor);
+ IM_PPIX(timg, x, y, &rcolor);
}
}
- for(l=0;l<im->xsize;l++) {
- for(i=0;i<im->ysize;i++) {
+ for(x = 0;x < im->xsize; x++) {
+ for(y = 0; y < im->ysize; y++) {
pc=0.0;
for(ch=0; ch<im->channels; ch++)
res[ch]=0;
for(c=0; c < diameter; c++)
- if (IM_GPIX(timg,l,i+c-radius,&rcolor)!=-1) {
+ if (IM_GPIX(timg, x, y+c-radius, &rcolor)!=-1) {
for(ch=0;ch<im->channels;ch++)
res[ch]+= rcolor.channel[ch] * coeff[c];
pc+=coeff[c];
double value = res[ch]/pc;
rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
}
- IM_PPIX(im,l,i,&rcolor);
+ IM_PPIX(im, x, y, &rcolor);
}
}
#/code
void
i_int_init_hlines(
i_int_hlines *hlines,
- int start_y,
- int count_y,
- int start_x,
- int width_x
+ i_img_dim start_y,
+ i_img_dim count_y,
+ i_img_dim start_x,
+ i_img_dim width_x
)
{
- int bytes = count_y * sizeof(i_int_hline_entry *);
+ size_t bytes = count_y * sizeof(i_int_hline_entry *);
if (bytes / count_y != sizeof(i_int_hline_entry *)) {
i_fatal(3, "integer overflow calculating memory allocation\n");
*/
void
-i_int_hlines_add(i_int_hlines *hlines, int y, int x, int width) {
- int x_limit = x + width;
+i_int_hlines_add(i_int_hlines *hlines, i_img_dim y, i_img_dim x, i_img_dim width) {
+ i_img_dim x_limit = x + width;
if (width < 0) {
i_fatal(3, "negative width %d passed to i_int_hlines_add\n", width);
if (hlines->entries[y - hlines->start_y]) {
i_int_hline_entry *entry = hlines->entries[y - hlines->start_y];
- int i, found = -1;
+ i_img_dim i, found = -1;
for (i = 0; i < entry->count; ++i) {
i_int_hline_seg *seg = entry->segs + i;
/* add a new segment */
if (entry->count == entry->alloc) {
/* expand it */
- int alloc = entry->alloc * 3 / 2;
+ size_t alloc = entry->alloc * 3 / 2;
entry = myrealloc(entry, sizeof(i_int_hline_entry) +
sizeof(i_int_hline_seg) * (alloc - 1));
entry->alloc = alloc;
void
i_int_hlines_destroy(i_int_hlines *hlines) {
- int entry_count = hlines->limit_y - hlines->start_y;
- int i;
+ size_t entry_count = hlines->limit_y - hlines->start_y;
+ size_t i;
for (i = 0; i < entry_count; ++i) {
if (hlines->entries[i])
void
i_int_hlines_fill_color(i_img *im, i_int_hlines *hlines, const i_color *col) {
- int y, i, x;
+ i_img_dim y, i, x;
for (y = hlines->start_y; y < hlines->limit_y; ++y) {
i_int_hline_entry *entry = hlines->entries[y - hlines->start_y];
void
i_int_hlines_fill_fill(i_img *im, i_int_hlines *hlines, i_fill_t *fill) {
i_render r;
- int y, i;
+ i_img_dim y, i;
i_render_init(&r, im, im->xsize);
if (entry) {
for (i = 0; i < entry->count; ++i) {
i_int_hline_seg *seg = entry->segs + i;
- int width = seg->x_limit-seg->minx;
+ i_img_dim width = seg->x_limit-seg->minx;
i_render_fill(&r, seg->minx, y, width, NULL, fill);
}
if (entry) {
for (i = 0; i < entry->count; ++i) {
i_int_hline_seg *seg = entry->segs + i;
- int width = seg->x_limit-seg->minx;
+ i_img_dim width = seg->x_limit-seg->minx;
if (fill->combine) {
i_glin(im, seg->minx, seg->x_limit, y, line);
if (entry) {
for (i = 0; i < entry->count; ++i) {
i_int_hline_seg *seg = entry->segs + i;
- int width = seg->x_limit-seg->minx;
+ i_img_dim width = seg->x_limit-seg->minx;
if (fill->combinef) {
i_glinf(im, seg->minx, seg->x_limit, y, line);
#define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i )) )
/* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
-static void fake(void) { ceil(1); }
+void i_linker_bug_fake(void) { ceil(1); }
/*
=item i_img_alloc()
void
i_img_exorcise(i_img *im) {
- mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
+ mm_log((1,"i_img_exorcise(im* %p)\n",im));
i_tags_destroy(&im->tags);
if (im->i_f_destroy)
(im->i_f_destroy)(im);
void
-i_img_info(i_img *im,int *info) {
- mm_log((1,"i_img_info(im 0x%x)\n",im));
+i_img_info(i_img *im, i_img_dim *info) {
+ mm_log((1,"i_img_info(im %p)\n",im));
if (im != NULL) {
- mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
- mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
+ mm_log((1,"i_img_info: xsize=%" i_DF " ysize=%" i_DF " channels=%d "
+ "mask=%ud\n",
+ i_DFc(im->xsize), i_DFc(im->ysize), im->channels,im->ch_mask));
+ mm_log((1,"i_img_info: idata=%p\n",im->idata));
info[0] = im->xsize;
info[1] = im->ysize;
info[2] = im->channels;
*/
void
-i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,const i_color *trans) {
+i_copyto_trans(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans) {
i_color pv;
- int x,y,t,ttx,tty,tt,ch;
+ i_img_dim x,y,t,ttx,tty,tt;
+ int ch;
- mm_log((1,"i_copyto_trans(im* %p,src 0x%x, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d, trans* 0x%x)\n",
- im, src, x1, y1, x2, y2, tx, ty, trans));
+ mm_log((1,"i_copyto_trans(im* %p,src %p, p1(" i_DFp "), p2(" i_DFp "), "
+ "to(" i_DFp "), trans* %p)\n",
+ im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty), trans));
if (x2<x1) { t=x1; x1=x2; x2=t; }
if (y2<y1) { t=y1; y1=y2; y2=t; }
i_img *
i_copy(i_img *src) {
- int y, y1, x1;
+ i_img_dim y, y1, x1;
i_img *im = i_sametype(src, src->xsize, src->ysize);
mm_log((1,"i_copy(src %p)\n", src));
return im;
}
+/*
+http://en.wikipedia.org/wiki/Lanczos_resampling
-
-
+*/
static
float
*/
i_img*
-i_scaleaxis(i_img *im, float Value, int Axis) {
- int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
- int LanczosWidthFactor;
- float *l0, *l1, OldLocation;
- int T;
- float t;
+i_scaleaxis(i_img *im, double Value, int Axis) {
+ i_img_dim hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
+ i_img_dim LanczosWidthFactor;
+ float *l0, *l1;
+ double OldLocation;
+ i_img_dim T;
+ double t;
float F, PictureValue[MAXCHANNELS];
short psave;
i_color val,val1,val2;
mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
if (Axis == XAXIS) {
- hsize = (int)(0.5 + im->xsize * Value);
+ hsize = (i_img_dim)(0.5 + im->xsize * Value);
if (hsize < 1) {
hsize = 1;
Value = 1.0 / im->xsize;
iEnd = vsize;
} else {
hsize = im->xsize;
- vsize = (int)(0.5 + im->ysize * Value);
+ vsize = (i_img_dim)(0.5 + im->ysize * Value);
if (vsize < 1) {
vsize = 1;
}
/* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
- LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
+ LanczosWidthFactor = (Value >= 1) ? 1 : (i_img_dim) (1.4/Value);
lMax = LanczosWidthFactor << 1;
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;
+ OldLocation = ((double) j) / Value;
+ T = (i_img_dim) (OldLocation);
+ F = OldLocation - T;
for (l = 0; l<lMax; l++) {
l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
t+=l0[l];
t+=l1[l];
}
- t /= (float)LanczosWidthFactor;
+ t /= (double)LanczosWidthFactor;
for(l=0; l<lMax; l++) {
l0[l] /= t;
for (i=0; i<iEnd; i++) {
for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
for (l=0; l<lMax; l++) {
- int mx = T-lMax+l+1;
- int Mx = T+l+1;
+ i_img_dim mx = T-lMax+l+1;
+ i_img_dim Mx = T+l+1;
mx = (mx < 0) ? 0 : mx;
Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
for (i=0; i<iEnd; i++) {
for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
for (l=0; l < lMax; l++) {
- int mx = T-lMax+l+1;
- int Mx = T+l+1;
+ i_img_dim mx = T-lMax+l+1;
+ i_img_dim Mx = T+l+1;
mx = (mx < 0) ? 0 : mx;
Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
i_img*
-i_scale_nn(i_img *im, float scx, float scy) {
+i_scale_nn(i_img *im, double scx, double scy) {
- int nxsize,nysize,nx,ny;
+ i_img_dim nxsize,nysize,nx,ny;
i_img *new_img;
i_color val;
- mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
+ mm_log((1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy));
- nxsize = (int) ((float) im->xsize * scx);
+ nxsize = (i_img_dim) ((double) im->xsize * scx);
if (nxsize < 1) {
nxsize = 1;
scx = 1.0 / im->xsize;
}
- nysize = (int) ((float) im->ysize * scy);
+ nysize = (i_img_dim) ((double) im->ysize * scy);
if (nysize < 1) {
nysize = 1;
scy = 1.0 / im->ysize;
new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
- i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
+ i_gpix(im,((double)nx)/scx,((double)ny)/scy,&val);
i_ppix(new_img,nx,ny,&val);
}
- mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
+ mm_log((1,"(%p) <- i_scale_nn\n",new_img));
return new_img;
}
=cut
*/
-i_img *i_sametype(i_img *src, int xsize, int ysize) {
+i_img *i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) {
if (src->type == i_direct_type) {
if (src->bits == 8) {
return i_img_empty_ch(NULL, xsize, ysize, src->channels);
=cut
*/
-i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
+i_img *i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) {
if (src->bits == 8) {
return i_img_empty_ch(NULL, xsize, ysize, channels);
}
i_img*
i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
double rx,ry;
- int nxsize,nysize,nx,ny;
+ i_img_dim nxsize,nysize,nx,ny;
i_img *new_img;
i_color val;
- mm_log((1,"i_transform(im 0x%x, opx 0x%x, opxl %d, opy 0x%x, opyl %d, parm 0x%x, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen));
+ mm_log((1,"i_transform(im %p, opx %p, opxl %d, opy %p, opyl %d, parm %p, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen));
nxsize = im->xsize;
nysize = im->ysize ;
i_ppix(new_img,nx,ny,&val);
}
- mm_log((1,"(0x%x) <- i_transform\n",new_img));
+ mm_log((1,"(%p) <- i_transform\n",new_img));
return new_img;
}
float
i_img_diff(i_img *im1,i_img *im2) {
- int x,y,ch,xb,yb,chb;
+ i_img_dim x, y, xb, yb;
+ int ch, chb;
float tdiff;
i_color val1,val2;
- mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
+ mm_log((1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2));
xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
- mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
+ mm_log((1,"i_img_diff: b=(" i_DFp ") chb=%d\n",
+ i_DFcp(xb,yb), chb));
tdiff=0;
for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
double
i_img_diffd(i_img *im1,i_img *im2) {
- int x,y,ch,xb,yb,chb;
+ i_img_dim x, y, xb, yb;
+ int ch, chb;
double tdiff;
i_fcolor val1,val2;
- mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
+ mm_log((1,"i_img_diffd(im1 %p,im2 %p)\n",im1,im2));
xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
- mm_log((1,"i_img_diffd: xb=%d xy=%d chb=%d\n",xb,yb,chb));
+ mm_log((1,"i_img_diffd: b(" i_DFp ") chb=%d\n",
+ i_DFcp(xb, yb), chb));
tdiff=0;
for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
int
i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
- int x,y,ch,xb,yb,chb;
+ i_img_dim x,y,xb,yb;
+ int ch, chb;
i_fcolor val1,val2;
if (what == NULL)
what = "(null)";
- mm_log((1,"i_img_samef(im1 0x%x,im2 0x%x, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
+ mm_log((1,"i_img_samef(im1 %p,im2 %p, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
- mm_log((1,"i_img_samef: xb=%d xy=%d chb=%d\n",xb,yb,chb));
+ mm_log((1,"i_img_samef: b(" i_DFp ") chb=%d\n",
+ i_DFcp(xb, yb), chb));
for(y = 0; y < yb; y++) {
for(x = 0; x < xb; x++) {
for(ch = 0; ch < chb; ch++) {
double sdiff = val1.channel[ch] - val2.channel[ch];
if (fabs(sdiff) > epsilon) {
- mm_log((1,"i_img_samef <- different %g @(%d,%d)\n", sdiff, x, y));
+ mm_log((1,"i_img_samef <- different %g @(" i_DFp ")\n",
+ sdiff, i_DFcp(x, y)));
return 0;
}
}
i_img*
i_haar(i_img *im) {
- int mx,my;
- int fx,fy;
- int x,y;
+ i_img_dim mx,my;
+ i_img_dim fx,fy;
+ i_img_dim x,y;
int ch,c;
i_img *new_img,*new_img2;
i_color val1,val2,dval1,dval2;
int
i_count_colors(i_img *im,int maxc) {
struct octt *ct;
- int x,y;
+ i_img_dim x,y;
int colorcnt;
int channels[3];
int *samp_chans;
i_sample_t * samp;
- int xsize = im->xsize;
- int ysize = im->ysize;
+ i_img_dim xsize = im->xsize;
+ i_img_dim ysize = im->ysize;
int samp_cnt = 3 * xsize;
if (im->channels >= 3) {
int
i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
struct octt *ct;
- int x,y;
+ i_img_dim x,y;
int colorcnt;
unsigned int *col_usage_it;
i_sample_t * samp;
int channels[3];
int *samp_chans;
- int xsize = im->xsize;
- int ysize = im->ysize;
+ i_img_dim xsize = im->xsize;
+ i_img_dim ysize = im->ysize;
int samp_cnt = 3 * xsize;
ct = octt_new();
=over
-=item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
+=item i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
=cut
*/
-int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
+int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
i_color temp;
int ch;
}
/*
-=item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
+=item i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
=cut
*/
-int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
+int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
i_color temp;
int ch;
}
/*
-=item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
+=item i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
=cut
*/
-int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
+i_img_dim
+i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix) {
i_color *work;
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
if (r > l) {
- int ret;
- int i, ch;
+ i_img_dim ret;
+ i_img_dim i;
+ int ch;
work = mymalloc(sizeof(i_color) * (r-l));
for (i = 0; i < r-l; ++i) {
for (ch = 0; ch < im->channels; ++ch)
}
/*
-=item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
+=item i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
=cut
*/
-int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
+i_img_dim
+i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix) {
i_color *work;
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
if (r > l) {
- int ret;
- int i, ch;
+ i_img_dim ret;
+ i_img_dim i;
+ int ch;
work = mymalloc(sizeof(i_color) * (r-l));
ret = i_plin(im, l, r, y, work);
for (i = 0; i < r-l; ++i) {
}
/*
-=item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
+=item i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp, int *chans, int chan_count)
=cut
*/
-int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
+
+i_img_dim
+i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
int const *chans, int chan_count) {
i_sample_t *work;
if (r > im->xsize)
r = im->xsize;
if (r > l) {
- int ret;
- int i;
+ i_img_dim ret;
+ i_img_dim i;
work = mymalloc(sizeof(i_sample_t) * (r-l));
ret = i_gsamp(im, l, r, y, work, chans, chan_count);
for (i = 0; i < ret; ++i) {
=cut
*/
-int
-i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
+i_img_dim
+i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
const int *chans, int chan_count, int bits) {
if (bits < 1 || bits > 32) {
i_push_error(0, "Invalid bits, must be 1..32");
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
double scale;
- int ch, count, i, w;
+ int ch;
+ i_img_dim count, i, w;
if (bits == 32)
scale = 4294967295.0;
Arnar M. Hrafnkelsson <addi@umich.edu>
-Tony Cook <tony@develop-help.com>
+Tony Cook <tonyc@cpan.org>
=head1 SEE ALSO
extern void i_rgb_to_hsv(i_color *color);
extern void i_hsv_to_rgb(i_color *color);
-i_img *IIM_new(int x,int y,int ch);
+i_img *IIM_new(i_img_dim x,i_img_dim y,int ch);
#define i_img_8_new IIM_new
void IIM_DESTROY(i_img *im);
i_img *i_img_new( void );
-i_img *i_img_empty(i_img *im,int x,int y);
-i_img *i_img_empty_ch(i_img *im,int x,int y,int ch);
+i_img *i_img_empty(i_img *im,i_img_dim x,i_img_dim y);
+i_img *i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch);
void i_img_exorcise(i_img *im);
void i_img_destroy(i_img *im);
i_img *i_img_alloc(void);
void i_img_init(i_img *im);
-void i_img_info(i_img *im,int *info);
+void i_img_info(i_img *im,i_img_dim *info);
-extern i_img *i_sametype(i_img *im, int xsize, int ysize);
-extern i_img *i_sametype_chans(i_img *im, int xsize, int ysize, int channels);
+extern i_img *i_sametype(i_img *im, i_img_dim xsize, i_img_dim ysize);
+extern i_img *i_sametype_chans(i_img *im, i_img_dim xsize, i_img_dim ysize, int channels);
-i_img *i_img_pal_new(int x, int y, int ch, int maxpal);
+i_img *i_img_pal_new(i_img_dim x, i_img_dim y, int ch, int maxpal);
/* Image feature settings */
/* Base functions */
-extern int i_ppix(i_img *im,int x,int y, const i_color *val);
-extern int i_gpix(i_img *im,int x,int y,i_color *val);
-extern int i_ppixf(i_img *im,int x,int y, const i_fcolor *val);
-extern int i_gpixf(i_img *im,int x,int y,i_fcolor *val);
+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);
#define i_ppix(im, x, y, val) (((im)->i_f_ppix)((im), (x), (y), (val)))
#define i_gpix(im, x, y, val) (((im)->i_f_gpix)((im), (x), (y), (val)))
#define i_ppixf(im, x, y, val) (((im)->i_f_ppixf)((im), (x), (y), (val)))
#define i_gpixf(im, x, y, val) (((im)->i_f_gpixf)((im), (x), (y), (val)))
-extern int i_plin(i_img *im, int l, int r, int y, const i_color *vals);
-extern int i_glin(i_img *im, int l, int r, int y, i_color *vals);
-extern int i_plinf(i_img *im, int l, int r, int y, const i_fcolor *vals);
-extern int i_glinf(i_img *im, int l, int r, int y, i_fcolor *vals);
-extern int i_gsamp(i_img *im, int l, int r, int y, i_sample_t *samp,
+extern i_img_dim i_plin(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+extern i_img_dim i_glin(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+extern i_img_dim i_plinf(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+extern i_img_dim i_glinf(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+extern i_img_dim i_gsamp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
const int *chans, int chan_count);
-extern int i_gsampf(i_img *im, int l, int r, int y, i_fsample_t *samp,
+extern i_img_dim i_gsampf(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
const int *chans, int chan_count);
-extern int i_gpal(i_img *im, int x, int r, int y, i_palidx *vals);
-extern int i_ppal(i_img *im, int x, int r, int y, const i_palidx *vals);
+extern i_img_dim i_gpal(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_palidx *vals);
+extern i_img_dim i_ppal(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_palidx *vals);
extern int i_addcolors(i_img *im, const i_color *colors, int count);
extern int i_getcolors(i_img *im, int i, i_color *, int count);
extern int i_colorcount(i_img *im);
extern i_fill_t *i_new_fill_solid(const i_color *c, int combine);
extern i_fill_t *
i_new_fill_hatch(const i_color *fg, const i_color *bg, int combine, int hatch,
- const unsigned char *cust_hatch, int dx, int dy);
+ const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy);
extern i_fill_t *
i_new_fill_hatchf(const i_fcolor *fg, const i_fcolor *bg, int combine, int hatch,
- const unsigned char *cust_hatch, int dx, int dy);
+ const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy);
extern i_fill_t *
-i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combine);
+i_new_fill_image(i_img *im, const double *matrix, i_img_dim xoff, i_img_dim yoff, int combine);
extern i_fill_t *i_new_fill_opacity(i_fill_t *, double alpha_mult);
extern void i_fill_destroy(i_fill_t *fill);
-float i_gpix_pch(i_img *im,int x,int y,int ch);
+float i_gpix_pch(i_img *im,i_img_dim x,i_img_dim y,int ch);
/* functions for drawing primitives */
-void i_box (i_img *im,int x1,int y1,int x2,int y2,const i_color *val);
-void i_box_filled (i_img *im,int x1,int y1,int x2,int y2,const i_color *val);
-int i_box_filledf (i_img *im,int x1,int y1,int x2,int y2,const i_fcolor *val);
-void i_box_cfill(i_img *im, int x1, int y1, int x2, int y2, i_fill_t *fill);
-void i_line (i_img *im,int x1,int y1,int x2,int y2,const i_color *val, int endp);
-void i_line_aa (i_img *im,int x1,int y1,int x2,int y2,const i_color *val, int endp);
-void i_arc (i_img *im,int x,int y,float rad,float d1,float d2,const i_color *val);
-int i_arc_out(i_img *im,i_img_dim x,i_img_dim y,i_img_dim rad,float d1,float d2,const i_color *val);
-int i_arc_out_aa(i_img *im,i_img_dim x,i_img_dim y,i_img_dim rad,float d1,float d2,const i_color *val);
+void i_box (i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val);
+void i_box_filled (i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val);
+int i_box_filledf (i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_fcolor *val);
+void i_box_cfill(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_fill_t *fill);
+void i_line (i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val, int endp);
+void i_line_aa (i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val, int endp);
+void i_arc (i_img *im,i_img_dim x,i_img_dim y,double rad,double d1,double d2,const i_color *val);
+int i_arc_out(i_img *im,i_img_dim x,i_img_dim y,i_img_dim rad,double d1,double d2,const i_color *val);
+int i_arc_out_aa(i_img *im,i_img_dim x,i_img_dim y,i_img_dim rad,double d1,double d2,const i_color *val);
void i_arc_aa (i_img *im, double x, double y, double rad, double d1, double d2, const i_color *val);
-void i_arc_cfill(i_img *im,int x,int y,float rad,float d1,float d2,i_fill_t *fill);
+void i_arc_cfill(i_img *im,i_img_dim x,i_img_dim y,double rad,double d1,double d2,i_fill_t *fill);
void i_arc_aa_cfill(i_img *im,double x,double y,double rad,double d1,double d2,i_fill_t *fill);
-void i_circle_aa (i_img *im,float x, float y,float rad,const i_color *val);
+void i_circle_aa (i_img *im,double x, double y,double rad,const i_color *val);
int i_circle_out (i_img *im,i_img_dim x, i_img_dim y, i_img_dim rad,const i_color *val);
int i_circle_out_aa (i_img *im,i_img_dim x, i_img_dim y, i_img_dim rad,const i_color *val);
-void i_copyto (i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
-void i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,const i_color *trans);
+void i_copyto (i_img *im,i_img *src,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(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans);
i_img* i_copy (i_img *src);
-int i_rubthru (i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+int i_rubthru (i_img *im, i_img *src, 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);
extern int
i_compose_mask(i_img *out, i_img *src, i_img *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);
extern int
i_compose(i_img *out, i_img *src,
- int out_left, int out_top, int src_left, int src_top,
- int width, int height, int combine, double opacity);
+ 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);
extern i_img *
i_combine(i_img **src, const int *channels, int in_count);
extern i_img *i_rotate90(i_img *im, int degrees);
extern i_img *i_rotate_exact(i_img *im, double amount);
extern i_img *i_rotate_exact_bg(i_img *im, double amount, const i_color *backp, const i_fcolor *fbackp);
-extern i_img *i_matrix_transform(i_img *im, int xsize, int ysize, const double *matrix);
-extern i_img *i_matrix_transform_bg(i_img *im, int xsize, int ysize, const double *matrix, const i_color *backp, const i_fcolor *fbackp);
+extern i_img *i_matrix_transform(i_img *im, i_img_dim xsize, i_img_dim ysize, const double *matrix);
+extern i_img *i_matrix_transform_bg(i_img *im, i_img_dim xsize, i_img_dim ysize, const double *matrix, const i_color *backp, const i_fcolor *fbackp);
void i_bezier_multi(i_img *im,int l,const double *x,const double *y,const i_color *val);
int i_poly_aa (i_img *im,int l,const double *x,const double *y,const i_color *val);
int i_poly_aa_cfill(i_img *im,int l,const double *x,const double *y,i_fill_t *fill);
-undef_int i_flood_fill (i_img *im,int seedx,int seedy, const i_color *dcol);
-undef_int i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill);
-undef_int i_flood_fill_border (i_img *im,int seedx,int seedy, const i_color *dcol, const i_color *border);
-undef_int i_flood_cfill_border(i_img *im, int seedx, int seedy, i_fill_t *fill, const i_color *border);
+undef_int i_flood_fill (i_img *im,i_img_dim seedx,i_img_dim seedy, const i_color *dcol);
+undef_int i_flood_cfill(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill);
+undef_int i_flood_fill_border (i_img *im,i_img_dim seedx,i_img_dim seedy, const i_color *dcol, const i_color *border);
+undef_int i_flood_cfill_border(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill, const i_color *border);
/* image processing functions */
undef_int i_init_fonts( int t1log );
-#ifdef HAVE_LIBT1
-
-undef_int i_init_t1( int t1log );
-int i_t1_new( char *pfb, char *afm );
-int i_t1_destroy( int font_id );
-undef_int i_t1_cp( i_img *im, int xb, int yb, int channel, int fontnum, float points, char* str, size_t len, int align, int utf8, char const *flags );
-undef_int i_t1_text( i_img *im, int xb, int yb, const i_color *cl, int fontnum, float points, const char* str, size_t len, int align, int utf8, char const *flags );
-int i_t1_bbox( int fontnum, float point, const char *str, size_t len, int cords[6], int utf8, char const *flags );
-void i_t1_set_aa( int st );
-void close_t1( void );
-int i_t1_has_chars(int font_num, char const *text, size_t len, int utf8, char *out);
-extern int i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size);
-extern int i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
- size_t name_buf_size);
-#endif
-
#ifdef HAVE_LIBTT
undef_int i_init_tt( void );
TT_Fonthandle* i_tt_new(const char *fontname);
void i_tt_destroy( TT_Fonthandle *handle );
-undef_int i_tt_cp( TT_Fonthandle *handle,i_img *im,int xb,int yb,int channel,float points,char const* txt,size_t len,int smooth, int utf8, int align);
-undef_int i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, const i_color *cl, float points, char const* txt, size_t len, int smooth, int utf8, int align);
-undef_int i_tt_bbox( TT_Fonthandle *handle, float points,const char *txt,size_t len,int cords[6], int utf8);
-int i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8, char *out);
+undef_int i_tt_cp( TT_Fonthandle *handle,i_img *im,i_img_dim xb,i_img_dim yb,int channel,double points,char const* txt,size_t len,int smooth, int utf8, int align);
+undef_int i_tt_text( TT_Fonthandle *handle, i_img *im, i_img_dim xb, i_img_dim yb, const i_color *cl, double points, char const* txt, size_t len, int smooth, int utf8, int align);
+undef_int i_tt_bbox( TT_Fonthandle *handle, double points,const char *txt,size_t len,i_img_dim cords[6], int utf8);
+size_t i_tt_has_chars(TT_Fonthandle *handle, char const *text, size_t len, int utf8, char *out);
void i_tt_dump_names(TT_Fonthandle *handle);
-int i_tt_face_name(TT_Fonthandle *handle, char *name_buf,
+size_t i_tt_face_name(TT_Fonthandle *handle, char *name_buf,
size_t name_buf_size);
-int i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf,
+size_t i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf,
size_t name_buf_size);
#endif /* End of freetype headers */
extern i_palidx *i_quant_translate(i_quantize *quant, i_img *img);
extern void i_quant_transparent(i_quantize *quant, i_palidx *indices, i_img *img, i_palidx trans_index);
-extern i_img *i_img_pal_new(int x, int y, int channels, int maxpal);
+extern i_img *i_img_pal_new(i_img_dim x, i_img_dim y, int channels, int maxpal);
extern i_img *i_img_to_pal(i_img *src, i_quantize *quant);
extern i_img *i_img_to_rgb(i_img *src);
-extern i_img *i_img_masked_new(i_img *targ, i_img *mask, int x, int y,
- int w, int h);
-extern i_img *i_img_16_new(int x, int y, int ch);
+extern i_img *i_img_masked_new(i_img *targ, i_img *mask, i_img_dim x, i_img_dim y,
+ i_img_dim w, i_img_dim h);
+extern i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch);
extern i_img *i_img_to_rgb16(i_img *im);
-extern i_img *i_img_double_new(int x, int y, int ch);
+extern i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch);
extern i_img *i_img_to_drgb(i_img *im);
extern int i_img_is_monochrome(i_img *im, int *zero_is_white);
const char * i_test_format_probe(io_glue *data, int length);
-#ifdef HAVE_LIBJPEG
-i_img *
-i_readjpeg_wiol(io_glue *ig, int length, char** iptc_itext, int *itlength);
-undef_int i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor);
-#endif /* HAVE_LIBJPEG */
-
-i_img * i_readraw_wiol(io_glue *ig, int x, int y, int datachannels, int storechannels, int intrl);
+i_img * i_readraw_wiol(io_glue *ig, i_img_dim x, i_img_dim y, int datachannels, int storechannels, int intrl);
undef_int i_writeraw_wiol(i_img* im, io_glue *ig);
i_img * i_readpnm_wiol(io_glue *ig, int allow_incomplete);
i_img * i_readrgb_wiol(io_glue *ig, int length);
undef_int i_writergb_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen);
-i_img * i_scaleaxis(i_img *im, float Value, int Axis);
-i_img * i_scale_nn(i_img *im, float scx, float scy);
-i_img * i_scale_mixing(i_img *src, int width, int height);
+i_img * i_scaleaxis(i_img *im, double Value, int Axis);
+i_img * i_scale_nn(i_img *im, double scx, double scy);
+i_img * i_scale_mixing(i_img *src, i_img_dim width, i_img_dim height);
i_img * i_haar(i_img *im);
int i_count_colors(i_img *im,int maxc);
int i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc);
-i_img * i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen);
+i_img * i_transform(i_img *im, int *opx, int opxl, int *opy,int opyl,double parm[],int parmlen);
struct rm_op;
-i_img * i_transform2(int width, int height, int channels,
+i_img * i_transform2(i_img_dim width, i_img_dim height, int channels,
struct rm_op *ops, int ops_count,
double *n_regs, int n_regs_count,
i_color *c_regs, int c_regs_count,
void i_hardinvert(i_img *im);
void i_hardinvertall(i_img *im);
void i_noise(i_img *im, float amount, unsigned char type);
-void i_bumpmap(i_img *im,i_img *bump,int channel,int light_x,int light_y,int strength);
-void i_bumpmap_complex(i_img *im, i_img *bump, int channel, int tx, int ty, float Lx, float Ly,
- float Lz, float cd, float cs, float n, i_color *Ia, i_color *Il, i_color *Is);
+void i_bumpmap(i_img *im,i_img *bump,int channel,i_img_dim light_x,i_img_dim light_y,i_img_dim strength);
+void i_bumpmap_complex(i_img *im, i_img *bump, int channel, i_img_dim tx, i_img_dim ty, double Lx, double Ly,
+ double Lz, float cd, float cs, float n, i_color *Ia, i_color *Il, i_color *Is);
void i_postlevels(i_img *im,int levels);
-void i_mosaic(i_img *im,int size);
-void i_watermark(i_img *im,i_img *wmark,int tx,int ty,int pixdiff);
+void i_mosaic(i_img *im,i_img_dim size);
+void i_watermark(i_img *im,i_img *wmark,i_img_dim tx,i_img_dim ty,int pixdiff);
void i_autolevels(i_img *im,float lsat,float usat,float skew);
-void i_radnoise(i_img *im,int xo,int yo,float rscale,float ascale);
-void i_turbnoise(i_img *im,float xo,float yo,float scale);
-void i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
-int i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
+void i_radnoise(i_img *im,i_img_dim xo,i_img_dim yo,double rscale,double ascale);
+void i_turbnoise(i_img *im,double xo,double yo,double scale);
+void i_gradgen(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *ival, int dmeasure);
+int i_nearest_color(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *ival, int dmeasure);
i_img *i_diff_image(i_img *im, i_img *im2, double mindist);
int
i_fountain(i_img *im, double xa, double ya, double xb, double yb,
void (*ICL_info)(const i_color *cl);
i_img*(*i_img_new)( void );
- i_img*(*i_img_empty)(i_img *im,int x,int y);
- i_img*(*i_img_empty_ch)(i_img *im,int x,int y,int ch);
+ i_img*(*i_img_empty)(i_img *im,i_img_dim x,i_img_dim y);
+ i_img*(*i_img_empty_ch)(i_img *im,i_img_dim x,i_img_dim y,int ch);
void(*i_img_exorcise)(i_img *im);
- void(*i_img_info)(i_img *im,int *info);
+ void(*i_img_info)(i_img *im,i_img_dim *info);
void(*i_img_setmask)(i_img *im,int ch_mask);
int (*i_img_getmask)(i_img *im);
/*
- int (*i_ppix)(i_img *im,int x,int y,i_color *val);
- int (*i_gpix)(i_img *im,int x,int y,i_color *val);
+ int (*i_ppix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val);
+ int (*i_gpix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val);
*/
- void(*i_box)(i_img *im,int x1,int y1,int x2,int y2,const i_color *val);
- void(*i_line)(i_img *im,int x1,int y1,int x2,int y2,const i_color *val,int endp);
- void(*i_arc)(i_img *im,int x,int y,float rad,float d1,float d2,const i_color *val);
- void(*i_copyto)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
- void(*i_copyto_trans)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,const i_color *trans);
- int(*i_rubthru)(i_img *im,i_img *src,int tx,int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+ void(*i_box)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val);
+ void(*i_line)(i_img *im,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,const i_color *val,int endp);
+ void(*i_arc)(i_img *im,i_img_dim x,i_img_dim y,double rad,double d1,double d2,const i_color *val);
+ void(*i_copyto)(i_img *im,i_img *src,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)(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans);
+ int(*i_rubthru)(i_img *im,i_img *src,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);
} symbol_table_t;
/* image file limits */
extern int
-i_set_image_file_limits(int width, int height, int bytes);
+i_set_image_file_limits(i_img_dim width, i_img_dim height, size_t bytes);
extern int
-i_get_image_file_limits(int *width, int *height, int *bytes);
+i_get_image_file_limits(i_img_dim *width, i_img_dim *height, size_t *bytes);
extern int
-i_int_check_image_file_limits(int width, int height, int channels, int sample_size);
+i_int_check_image_file_limits(i_img_dim width, i_img_dim height, int channels, size_t sample_size);
/* memory allocation */
-void* mymalloc(int size);
+void* mymalloc(size_t size);
void myfree(void *p);
void* myrealloc(void *p, size_t newsize);
void* mymalloc_file_line (size_t size, char* file, int line);
#define myfree(x) (myfree_file_line((x), __FILE__, __LINE__))
void malloc_state (void);
-void* mymalloc_comm (int size, char *comm);
void bndcheck_all (void);
#else
-#define malloc_comm(a,b) (mymalloc(a))
void malloc_state(void);
#endif /* IMAGER_MALLOC_DEBUG */
size_t count, i_fcolor const *bg);
extern int
-i_gsamp_bg(i_img *im, int l, int r, int y, i_sample_t *samples,
+i_gsamp_bg(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samples,
int out_channels, i_color const *bg);
extern int
-i_gsampf_bg(i_img *im, int l, int r, int y, i_fsample_t *samples,
+i_gsampf_bg(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samples,
int out_channels, i_fcolor const *bg);
+#include "imio.h"
+
#endif
/* wrapper functions that implement the floating point sample version of a
function in terms of the 8-bit sample version
*/
-extern int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix);
-extern int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix);
-extern int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix);
-extern int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix);
-extern int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
+extern int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix);
+extern int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix);
+extern i_img_dim i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix);
+extern i_img_dim i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix);
+extern i_img_dim i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
int const *chans, int chan_count);
/* wrapper functions that forward palette calls to the underlying image,
int count);
/* fallback handler for gsamp_bits */
-extern int i_gsamp_bits_fb(i_img *im, int x, int r, int y, unsigned *samp,
+extern i_img_dim i_gsamp_bits_fb(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, unsigned *samp,
const int *chans, int chan_count, int bits);
#define SampleFTo16(num) ((int)((num) * 65535.0 + 0.01))
#define I_ALL_CHANNELS_WRITABLE(im) (((im)->ch_mask & 0xF) == 0xf)
typedef struct i_int_hline_seg_tag {
- int minx, x_limit;
+ i_img_dim minx, x_limit;
} i_int_hline_seg;
typedef struct i_int_hline_entry_tag {
- int count;
- int alloc;
+ i_img_dim count;
+ size_t alloc;
i_int_hline_seg segs[1];
} i_int_hline_entry;
/* represents a set of horizontal line segments to be filled in later */
typedef struct i_int_hlines_tag {
- int start_y, limit_y;
- int start_x, limit_x;
+ i_img_dim start_y, limit_y;
+ i_img_dim start_x, limit_x;
i_int_hline_entry **entries;
} i_int_hlines;
extern void
i_int_init_hlines(
i_int_hlines *hlines,
- int start_y,
- int count_y,
- int start_x,
- int width_x
+ i_img_dim start_y,
+ i_img_dim count_y,
+ i_img_dim start_x,
+ i_img_dim width_x
);
extern void i_int_init_hlines_img(i_int_hlines *hlines, i_img *img);
-extern void i_int_hlines_add(i_int_hlines *hlines, int y, int minx, int width);
+extern void i_int_hlines_add(i_int_hlines *hlines, i_img_dim y, i_img_dim minx, i_img_dim width);
extern void i_int_hlines_destroy(i_int_hlines *hlines);
extern void i_int_hlines_fill_color(i_img *im, i_int_hlines *hlines, const i_color *val);
i_img_dim i_minx(i_img_dim a, i_img_dim b);
i_img_dim i_maxx(i_img_dim x, i_img_dim y);
+i_img_dim i_abs(i_img_dim x);
#define i_min(a, b) i_minx((a), (b))
#define i_max(a, b) i_maxx((a), (b))
#include <stddef.h>
#include "imconfig.h"
-#include "imio.h"
#define MAXCHANNELS 4
typedef int undef_int; /* special value to put in typemaps to retun undef on 0 and 1 on 1 */
+/*
+=item i_img_dim
+=category Data Types
+=synopsis i_img_dim x, y;
+=order 90
+
+A signed integer type that represents an image dimension or ordinate.
+
+May be larger than int on some platforms.
+
+=cut
+*/
+
+typedef ptrdiff_t i_img_dim;
+
/*
=item i_color
=category Data Types
} i_img_tags;
typedef struct i_img_ i_img;
-typedef int (*i_f_ppix_t)(i_img *im, int x, int y, const i_color *pix);
-typedef int (*i_f_ppixf_t)(i_img *im, int x, int y, const i_fcolor *pix);
-typedef int (*i_f_plin_t)(i_img *im, int x, int r, int y, const i_color *vals);
-typedef int (*i_f_plinf_t)(i_img *im, int x, int r, int y, const i_fcolor *vals);
-typedef int (*i_f_gpix_t)(i_img *im, int x, int y, i_color *pix);
-typedef int (*i_f_gpixf_t)(i_img *im, int x, int y, i_fcolor *pix);
-typedef int (*i_f_glin_t)(i_img *im, int x, int r, int y, i_color *vals);
-typedef int (*i_f_glinf_t)(i_img *im, int x, int r, int y, i_fcolor *vals);
-
-typedef int (*i_f_gsamp_t)(i_img *im, int x, int r, int y, i_sample_t *samp,
+typedef int (*i_f_ppix_t)(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix);
+typedef int (*i_f_ppixf_t)(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix);
+typedef i_img_dim (*i_f_plin_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_color *vals);
+typedef i_img_dim (*i_f_plinf_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+typedef int (*i_f_gpix_t)(i_img *im, i_img_dim x, i_img_dim y, i_color *pix);
+typedef int (*i_f_gpixf_t)(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix);
+typedef i_img_dim (*i_f_glin_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_color *vals);
+typedef i_img_dim (*i_f_glinf_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_fcolor *vals);
+
+typedef i_img_dim (*i_f_gsamp_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_sample_t *samp,
const int *chans, int chan_count);
-typedef int (*i_f_gsampf_t)(i_img *im, int x, int r, int y, i_fsample_t *samp,
+typedef i_img_dim (*i_f_gsampf_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_fsample_t *samp,
const int *chan, int chan_count);
-typedef int (*i_f_gpal_t)(i_img *im, int x, int r, int y, i_palidx *vals);
-typedef int (*i_f_ppal_t)(i_img *im, int x, int r, int y, const i_palidx *vals);
+typedef i_img_dim (*i_f_gpal_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_palidx *vals);
+typedef i_img_dim (*i_f_ppal_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_palidx *vals);
typedef int (*i_f_addcolors_t)(i_img *im, const i_color *colors, int count);
typedef int (*i_f_getcolors_t)(i_img *im, int i, i_color *, int count);
typedef int (*i_f_colorcount_t)(i_img *im);
typedef void (*i_f_destroy_t)(i_img *im);
-typedef int (*i_f_gsamp_bits_t)(i_img *im, int x, int r, int y, unsigned *samp,
+typedef i_img_dim (*i_f_gsamp_bits_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, unsigned *samp,
const int *chans, int chan_count, int bits);
-typedef int (*i_f_psamp_bits_t)(i_img *im, int x, int r, int y, unsigned const *samp,
+typedef i_img_dim (*i_f_psamp_bits_t)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, unsigned const *samp,
const int *chans, int chan_count, int bits);
-/*
-=item i_img_dim
-=category Data Types
-=synopsis i_img_dim x;
-=order 90
-
-A signed integer type that represents an image dimension or ordinate.
-
-May be larger than int on some platforms.
-
-=cut
-*/
-
-typedef int i_img_dim;
-
/*
=item i_img
=category Data Types
/* bitmap mask */
struct i_bitmap {
- int xsize,ysize;
+ i_img_dim xsize,ysize;
char *data;
};
-struct i_bitmap* btm_new(int xsize,int ysize);
+struct i_bitmap* btm_new(i_img_dim xsize,i_img_dim ysize);
void btm_destroy(struct i_bitmap *btm);
-int btm_test(struct i_bitmap *btm,int x,int y);
-void btm_set(struct i_bitmap *btm,int x,int y);
+int btm_test(struct i_bitmap *btm,i_img_dim x,i_img_dim y);
+void btm_set(struct i_bitmap *btm,i_img_dim x,i_img_dim y);
/* Stack/Linked list */
struct llist {
struct llink *h,*t;
int multip; /* # of copies in a single chain */
- int ssize; /* size of each small element */
+ size_t ssize; /* size of each small element */
int count; /* number of elements on the list */
};
-/* Links */
-
-struct llink *llink_new( struct llink* p,int size );
-int llist_llink_push( struct llist *lst, struct llink *lnk, void *data );
-
/* Lists */
-struct llist *llist_new( int multip, int ssize );
+struct llist *llist_new( int multip, size_t ssize );
void llist_destroy( struct llist *l );
-void llist_push( struct llist *l, void *data );
+void llist_push( struct llist *l, const void *data );
void llist_dump( struct llist *l );
int llist_pop( struct llist *l,void *data );
typedef struct i_render_tag i_render;
+#ifdef IMAGER_FORMAT_ATTR
+#define I_FORMAT_ATTR(format_index, va_index) \
+ __attribute ((format (printf, format_index, va_index)))
+#else
+#define I_FORMAT_ATTR(format_index, va_index)
+#endif
+
+/*
+=item i_DF
+=category Data Types
+=synopsis printf("left %" i_DF "\n", i_DFc(x));
+=order 95
+
+This is a constant string that can be used with functions like
+printf() to format i_img_dim values after they're been cast with i_DFc().
+
+Does not include the leading C<%>.
+
+=cut
+
+=item i_DFc
+=category Data Types
+=order 95
+
+Cast an C<i_img_dim> value to a type for use with the i_DF format
+string.
+
+=cut
+
+=item i_DFp
+=category Data Types
+=synopsis printf("point (" i_DFp ")\n", i_DFcp(x, y));
+=order 95
+
+Format a pair of C<i_img_dim> values. This format string I<does>
+include the leading C<%>.
+
+=cut
+
+=item i_DFcp
+=category Data Types
+=order 95
+
+Casts two C<i_img_dim> values for use with the i_DF (or i_DFp) format.
+
+=cut
+ */
+
+#define i_DFc(x) ((i_dim_format_t)(x))
+#define i_DFcp(x, y) i_DFc(x), i_DFc(y)
+#define i_DFp "%" i_DF ", %" i_DF
+
#endif
extern i_errmsg *i_errors(void);
extern void i_push_error(int code, char const *msg);
-extern void i_push_errorf(int code, char const *fmt, ...);
+extern void i_push_errorf(int code, char const *fmt, ...) I_FORMAT_ATTR(2, 3);
extern void i_push_errorvf(int code, char const *fmt, va_list);
extern void i_clear_error(void);
extern int i_failed(int code, char const *msg);
*/
int
-(i_ppix)(i_img *im, int x, int y, const i_color *val) {
+(i_ppix)(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
return i_ppix(im, x, y, val);
}
*/
int
-(i_gpix)(i_img *im,int x,int y,i_color *val) {
+(i_gpix)(i_img *im,i_img_dim x,i_img_dim y,i_color *val) {
return i_gpix(im, x, y, val);
}
=cut
*/
int
-(i_ppixf)(i_img *im, int x, int y, const i_fcolor *val) {
+(i_ppixf)(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
return i_ppixf(im, x, y, val);
}
*/
int
-(i_gpixf)(i_img *im,int x,int y,i_fcolor *val) {
+(i_gpixf)(i_img *im,i_img_dim x,i_img_dim y,i_fcolor *val) {
return i_gpixf(im, x, y, val);
}
=cut
*/
-int
-(i_plin)(i_img *im, int l, int r, int y, const i_color *vals) {
+i_img_dim
+(i_plin)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
return i_plin(im, l, r, y, vals);
}
=cut
*/
-int
-(i_glin)(i_img *im, int l, int r, int y, i_color *vals) {
+i_img_dim
+(i_glin)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
return i_glin(im, l, r, y, vals);
}
=cut
*/
-int
-(i_plinf)(i_img *im, int l, int r, int y, const i_fcolor *vals) {
+i_img_dim
+(i_plinf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
return i_plinf(im, l, r, y, vals);
}
=cut
*/
-int
-(i_glinf)(i_img *im, int l, int r, int y, i_fcolor *vals) {
+i_img_dim
+(i_glinf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
return i_glinf(im, l, r, y, vals);
}
=cut
*/
-int
-(i_gsamp)(i_img *im, int l, int r, int y, i_sample_t *samp,
+i_img_dim
+(i_gsamp)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
const int *chans, int chan_count) {
return i_gsamp(im, l, r, y, samp, chans, chan_count);
}
=cut
*/
-int
-(i_gsampf)(i_img *im, int l, int r, int y, i_fsample_t *samp,
+i_img_dim
+(i_gsampf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
const int *chans, int chan_count) {
return i_gsampf(im, l, r, y, samp, chans, chan_count);
}
=cut
*/
-int
-(i_gpal)(i_img *im, int x, int r, int y, i_palidx *vals) {
+i_img_dim
+(i_gpal)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_palidx *vals) {
return i_gpal(im, x, r, y, vals);
}
=cut
*/
-int
-(i_ppal)(i_img *im, int x, int r, int y, const i_palidx *vals) {
+i_img_dim
+(i_ppal)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_palidx *vals) {
return i_ppal(im, x, r, y, vals);
}
#define i_render_linef(r, x, y, width, src, line, combine) \
((im_extt->f_i_render_linef)((r), (x), (y), (width), (src), (line), (combine)))
+#ifdef IMAGER_LOG
+#define mm_log(x) { i_lhead(__FILE__,__LINE__); i_loog x; }
+#else
+#define mm_log(x)
+#endif
+
+
#endif
/* keep this file simple - apidocs.perl parses it. */
#include "imdatatypes.h"
+#include <stdarg.h>
/*
IMAGER_API_VERSION is similar to the version number in the third and
fourth bytes of TIFF files - if it ever changes then the API has changed
too much for any application to remain compatible.
+
+ Version 2 changed the types of some parameters and pointers. A
+ simple recompile should be enough in most cases.
+
*/
-#define IMAGER_API_VERSION 1
+#define IMAGER_API_VERSION 2
/*
IMAGER_API_LEVEL is the level of the structure. New function pointers
int level;
/* IMAGER_API_LEVEL 1 functions */
- void * (*f_mymalloc)(int size);
+ void * (*f_mymalloc)(size_t size);
void (*f_myfree)(void *block);
void * (*f_myrealloc)(void *block, size_t newsize);
void* (*f_mymalloc_file_line)(size_t size, char* file, int line);
void (*f_myfree_file_line)(void *p, char*file, int line);
void* (*f_myrealloc_file_line)(void *p, size_t newsize, char* file,int line);
- i_img *(*f_i_img_8_new)(int xsize, int ysize, int channels);
- i_img *(*f_i_img_16_new)(int xsize, int ysize, int channels);
- i_img *(*f_i_img_double_new)(int xsize, int ysize, int channels);
- i_img *(*f_i_img_pal_new)(int xsize, int ysize, int channels, int maxpal);
+ i_img *(*f_i_img_8_new)(i_img_dim xsize, i_img_dim ysize, int channels);
+ i_img *(*f_i_img_16_new)(i_img_dim xsize, i_img_dim ysize, int channels);
+ i_img *(*f_i_img_double_new)(i_img_dim xsize, i_img_dim ysize, int channels);
+ i_img *(*f_i_img_pal_new)(i_img_dim xsize, i_img_dim ysize, int channels, int maxpal);
void (*f_i_img_destroy)(i_img *im);
- i_img *(*f_i_sametype)(i_img *im, int xsize, int ysize);
- i_img *(*f_i_sametype_chans)(i_img *im, int xsize, int ysize, int channels);
- void (*f_i_img_info)(i_img *im, int *info);
-
- int (*f_i_ppix)(i_img *im, int x, int y, const i_color *val);
- int (*f_i_gpix)(i_img *im, int x, int y, i_color *val);
- int (*f_i_ppixf)(i_img *im, int x, int y, const i_fcolor *val);
- int (*f_i_gpixf)(i_img *im, int x, int y, i_fcolor *val);
- int (*f_i_plin)(i_img *im, int l, int r, int y, const i_color *vals);
- int (*f_i_glin)(i_img *im, int l, int r, int y, i_color *vals);
- int (*f_i_plinf)(i_img *im, int l, int r, int y, const i_fcolor *vals);
- int (*f_i_glinf)(i_img *im, int l, int r, int y, i_fcolor *vals);
- int (*f_i_gsamp)(i_img *im, int l, int r, int y, i_sample_t *samp,
+ i_img *(*f_i_sametype)(i_img *im, i_img_dim xsize, i_img_dim ysize);
+ i_img *(*f_i_sametype_chans)(i_img *im, i_img_dim xsize, i_img_dim ysize, int channels);
+ void (*f_i_img_info)(i_img *im, i_img_dim *info);
+
+ int (*f_i_ppix)(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
+ int (*f_i_gpix)(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
+ int (*f_i_ppixf)(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val);
+ int (*f_i_gpixf)(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val);
+ i_img_dim (*f_i_plin)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+ i_img_dim (*f_i_glin)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+ i_img_dim (*f_i_plinf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+ i_img_dim (*f_i_glinf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+ i_img_dim (*f_i_gsamp)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
const int *chans, int chan_count);
- int (*f_i_gsampf)(i_img *im, int l, int r, int y, i_fsample_t *samp,
+ i_img_dim (*f_i_gsampf)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
const int *chans, int chan_count);
- int (*f_i_gpal)(i_img *im, int x, int r, int y, i_palidx *vals);
- int (*f_i_ppal)(i_img *im, int x, int r, int y, const i_palidx *vals);
+ i_img_dim (*f_i_gpal)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, i_palidx *vals);
+ i_img_dim (*f_i_ppal)(i_img *im, i_img_dim x, i_img_dim r, i_img_dim y, const i_palidx *vals);
int (*f_i_addcolors)(i_img *im, const i_color *colors, int count);
int (*f_i_getcolors)(i_img *im, int i, i_color *, int count);
int (*f_i_colorcount)(i_img *im);
i_fill_t *(*f_i_new_fill_hatch)(const i_color *fg, const i_color *bg, int combine,
int hatch, const unsigned char *cust_hatch,
- int dx, int dy);
+ i_img_dim dx, i_img_dim dy);
i_fill_t *(*f_i_new_fill_hatchf)(const i_fcolor *fg, const i_fcolor *bg, int combine,
int hatch, const unsigned char *cust_hatch,
- int dx, int dy);
- i_fill_t *(*f_i_new_fill_image)(i_img *im, const double *matrix, int xoff,
- int yoff, int combine);
+ i_img_dim dx, i_img_dim dy);
+ i_fill_t *(*f_i_new_fill_image)(i_img *im, const double *matrix, i_img_dim xoff,
+ i_img_dim yoff, int combine);
i_fill_t *(*f_i_new_fill_fount)(double xa, double ya, double xb, double yb,
i_fountain_type type, i_fountain_repeat repeat,
int combine, int super_sample, double ssample_param,
int (*f_i_tags_set_color)(i_img_tags *tags, char const *name, int code,
i_color const *value);
- void (*f_i_box)(i_img *im, int x1, int y1, int x2, int y2, const i_color *val);
- void (*f_i_box_filled)(i_img *im, int x1, int y1, int x2, int y2, const i_color *val);
- void (*f_i_box_cfill)(i_img *im, int x1, int y1, int x2, int y2, i_fill_t *fill);
- void (*f_i_line)(i_img *im, int x1, int y1, int x2, int y2, const i_color *val, int endp);
- void (*f_i_line_aa)(i_img *im, int x1, int y1, int x2, int y2, const i_color *val, int endp);
- void (*f_i_arc)(i_img *im, int x, int y, float rad, float d1, float d2, const i_color *val);
+ void (*f_i_box)(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val);
+ void (*f_i_box_filled)(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val);
+ void (*f_i_box_cfill)(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_fill_t *fill);
+ void (*f_i_line)(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val, int endp);
+ void (*f_i_line_aa)(i_img *im, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, const i_color *val, int endp);
+ void (*f_i_arc)(i_img *im, i_img_dim x, i_img_dim y, double rad, double d1, double d2, const i_color *val);
void (*f_i_arc_aa)(i_img *im, double x, double y, double rad, double d1, double d2, const i_color *val);
- void (*f_i_arc_cfill)(i_img *im, int x, int y, float rad, float d1, float d2, i_fill_t *val);
+ void (*f_i_arc_cfill)(i_img *im, i_img_dim x, i_img_dim y, double rad, double d1, double d2, i_fill_t *val);
void (*f_i_arc_aa_cfill)(i_img *im, double x, double y, double rad, double d1, double d2, i_fill_t *fill);
- void (*f_i_circle_aa)(i_img *im, float x, float y, float rad, const i_color *val);
- int (*f_i_flood_fill)(i_img *im, int seedx, int seedy, const i_color *dcol);
- int (*f_i_flood_cfill)(i_img *im, int seedx, int seedy, i_fill_t *fill);
+ void (*f_i_circle_aa)(i_img *im, double x, double y, double rad, const i_color *val);
+ int (*f_i_flood_fill)(i_img *im, i_img_dim seedx, i_img_dim seedy, const i_color *dcol);
+ int (*f_i_flood_cfill)(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill);
- void (*f_i_copyto)(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty);
- void (*f_i_copyto_trans)(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty, const i_color *trans);
+ void (*f_i_copyto)(i_img *im, i_img *src, 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 (*f_i_copyto_trans)(i_img *im, i_img *src, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_img_dim tx, i_img_dim ty, const i_color *trans);
i_img *(*f_i_copy)(i_img *im);
- int (*f_i_rubthru)(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+ int (*f_i_rubthru)(i_img *im, i_img *src, 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);
/* IMAGER_API_LEVEL 2 functions */
- int (*f_i_set_image_file_limits)(int width, int height, int bytes);
- int (*f_i_get_image_file_limits)(int *width, int *height, int *bytes);
- int (*f_i_int_check_image_file_limits)(int width, int height, int channels, int sample_size);
- int (*f_i_flood_fill_border)(i_img *im, int seedx, int seedy, const i_color *dcol, const i_color *border);
- int (*f_i_flood_cfill_border)(i_img *im, int seedx, int seedy, i_fill_t *fill, const i_color *border);
+ int (*f_i_set_image_file_limits)(i_img_dim width, i_img_dim height, size_t bytes);
+ int (*f_i_get_image_file_limits)(i_img_dim *width, i_img_dim *height, size_t *bytes);
+ int (*f_i_int_check_image_file_limits)(i_img_dim width, i_img_dim height, int channels, size_t sample_size);
+ int (*f_i_flood_fill_border)(i_img *im, i_img_dim seedx, i_img_dim seedy, const i_color *dcol, const i_color *border);
+ int (*f_i_flood_cfill_border)(i_img *im, i_img_dim seedx, i_img_dim seedy, i_fill_t *fill, const i_color *border);
/* IMAGER_API_LEVEL 3 functions */
void (*f_i_img_setmask)(i_img *im, int ch_mask);
/* IMAGER_API_LEVEL 5 functions will be added here */
/* added i_psampf?_bits macros */
int (*f_i_img_is_monochrome)(i_img *, int *zero_is_white);
- int (*f_i_gsamp_bg)(i_img *im, int l, int r, int y, i_sample_t *samples,
+ int (*f_i_gsamp_bg)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samples,
int out_channels, i_color const * bg);
- int (*f_i_gsampf_bg)(i_img *im, int l, int r, int y, i_fsample_t *samples,
+ int (*f_i_gsampf_bg)(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samples,
int out_channels, i_fcolor const * bg);
void (*f_i_get_file_background)(i_img *im, i_color *bg);
void (*f_i_get_file_backgroundf)(i_img *im, i_fcolor *bg);
=head1 SYNOPSIS
- i_img *im = i_img_16_new(int x, int y, int channels);
+ i_img *im = i_img_16_new(i_img_dim x, i_img_dim y, int channels);
# use like a normal image
=head1 DESCRIPTION
#include "imager.h"
#include "imageri.h"
-static int i_ppix_d16(i_img *im, int x, int y, const i_color *val);
-static int i_gpix_d16(i_img *im, int x, int y, i_color *val);
-static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals);
-static int i_plin_d16(i_img *im, int l, int r, int y, const i_color *vals);
-static int i_ppixf_d16(i_img *im, int x, int y, const i_fcolor *val);
-static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val);
-static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals);
-static int i_plinf_d16(i_img *im, int l, int r, int y, const i_fcolor *vals);
-static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
+static int i_ppix_d16(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
+static int i_gpix_d16(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
+static i_img_dim i_glin_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+static i_img_dim i_plin_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+static int i_ppixf_d16(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val);
+static int i_gpixf_d16(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val);
+static i_img_dim i_glinf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+static i_img_dim i_plinf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+static i_img_dim i_gsamp_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
int const *chans, int chan_count);
-static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
+static i_img_dim i_gsampf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
int const *chans, int chan_count);
-static int i_gsamp_bits_d16(i_img *im, int l, int r, int y, unsigned *samps,
+static i_img_dim i_gsamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
int const *chans, int chan_count, int bits);
-static int i_psamp_bits_d16(i_img *im, int l, int r, int y, unsigned const *samps,
+static i_img_dim i_psamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned const *samps,
int const *chans, int chan_count, int bits);
/*
=cut
*/
-i_img *i_img_16_new(int x, int y, int ch) {
+i_img *i_img_16_new(i_img_dim x, i_img_dim y, int ch) {
i_img *im;
- int bytes, line_bytes;
+ size_t bytes, line_bytes;
- mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
+ mm_log((1,"i_img_16_new(x %" i_DF ", y %" i_DF ", ch %d)\n",
+ i_DFc(x), i_DFc(y), ch));
if (x < 1 || y < 1) {
i_push_error(0, "Image sizes must be positive");
i_img_to_rgb16(i_img *im) {
i_img *targ;
i_fcolor *line;
- int y;
+ i_img_dim y;
targ = i_img_16_new(im->xsize, im->ysize, im->channels);
if (!targ)
return targ;
}
-static int i_ppix_d16(i_img *im, int x, int y, const i_color *val) {
- int off, ch;
+static int i_ppix_d16(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
- int off, ch;
+static int i_gpix_d16(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_ppixf_d16(i_img *im, int x, int y, const i_fcolor *val) {
- int off, ch;
+static int i_ppixf_d16(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
- int off, ch;
+static int i_gpixf_d16(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_glin_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_plin_d16(i_img *im, int l, int r, int y, const i_color *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_plin_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_glinf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_plinf_d16(i_img *im, int l, int r, int y, const i_fcolor *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_plinf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
+static i_img_dim i_gsamp_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
int const *chans, int chan_count) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
+static i_img_dim i_gsampf_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
int const *chans, int chan_count) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int
-i_gsamp_bits_d16(i_img *im, int l, int r, int y, unsigned *samps,
+static i_img_dim
+i_gsamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
int const *chans, int chan_count, int bits) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (bits != 16) {
return i_gsamp_bits_fb(im, l, r, y, samps, chans, chan_count, bits);
}
}
-static int
-i_psamp_bits_d16(i_img *im, int l, int r, int y, unsigned const *samps,
+static i_img_dim
+i_psamp_bits_d16(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned const *samps,
int const *chans, int chan_count, int bits) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (bits != 16) {
i_push_error(0, "Invalid bits for 16-bit image");
#include "imager.h"
#include "imageri.h"
-static int i_ppix_d(i_img *im, int x, int y, const i_color *val);
-static int i_gpix_d(i_img *im, int x, int y, i_color *val);
-static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
-static int i_plin_d(i_img *im, int l, int r, int y, const i_color *vals);
-static int i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val);
-static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
-static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
-static int i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals);
-static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
-static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
+static int i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
+static int i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
+static i_img_dim i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+static i_img_dim i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+static int i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val);
+static int i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val);
+static i_img_dim i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+static i_img_dim i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+static i_img_dim i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, const int *chans, int chan_count);
+static i_img_dim i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps, const int *chans, int chan_count);
/*
=item IIM_base_8bit_direct (static)
i_img *
-IIM_new(int x,int y,int ch) {
+IIM_new(i_img_dim x,i_img_dim y,int ch) {
i_img *im;
- mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
+
+ mm_log((1,"IIM_new(x %" i_DF ", y %" i_DF ", ch %d)\n",
+ i_DFc(x), i_DFc(y), ch));
im=i_img_empty_ch(NULL,x,y,ch);
*/
i_img *
-i_img_empty(i_img *im,int x,int y) {
- mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
+i_img_empty(i_img *im,i_img_dim x,i_img_dim y) {
+ mm_log((1,"i_img_empty(*im %p, x %" i_DF ", y %" i_DF ")\n",
+ im, i_DFc(x), i_DFc(y)));
return i_img_empty_ch(im, x, y, 3);
}
*/
i_img *
-i_img_empty_ch(i_img *im,int x,int y,int ch) {
- int bytes;
+i_img_empty_ch(i_img *im,i_img_dim x,i_img_dim y,int ch) {
+ size_t bytes;
- mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
+ mm_log((1,"i_img_empty_ch(*im %p, x %" i_DF ", y %" i_DF ", ch %d)\n",
+ im, i_DFc(x), i_DFc(y), ch));
if (x < 1 || y < 1) {
i_push_error(0, "Image sizes must be positive");
*/
static
int
-i_ppix_d(i_img *im, int x, int y, const i_color *val) {
+i_ppix_d(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
int ch;
if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
*/
static
int
-i_gpix_d(i_img *im, int x, int y, i_color *val) {
+i_gpix_d(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
int ch;
if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
for(ch=0;ch<im->channels;ch++)
=cut
*/
static
-int
-i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
- int ch, count, i;
+i_img_dim
+i_glin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
+ int ch;
+ i_img_dim count, i;
unsigned char *data;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
=cut
*/
static
-int
-i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
- int ch, count, i;
+i_img_dim
+i_plin_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
+ int ch;
+ i_img_dim count, i;
unsigned char *data;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
*/
static
int
-i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
+i_ppixf_d(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
int ch;
if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
*/
static
int
-i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
+i_gpixf_d(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
int ch;
if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
for(ch=0;ch<im->channels;ch++) {
=cut
*/
static
-int
-i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
- int ch, count, i;
+i_img_dim
+i_glinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
unsigned char *data;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
=cut
*/
static
-int
-i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
- int ch, count, i;
+i_img_dim
+i_plinf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
unsigned char *data;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
/*
-=item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
+=item i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, int *chans, int chan_count)
Reads sample values from im for the horizontal line (l, y) to (r-1,y)
for the channels specified by chans, an array of int with chan_count
=cut
*/
static
-int
-i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
+i_img_dim
+i_gsamp_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
const int *chans, int chan_count) {
- int ch, count, i, w;
+ int ch;
+ i_img_dim count, i, w;
unsigned char *data;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
}
/*
-=item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
+=item i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps, int *chans, int chan_count)
Reads sample values from im for the horizontal line (l, y) to (r-1,y)
for the channels specified by chan_mask, where bit 0 is the first
=cut
*/
static
-int
-i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
+i_img_dim
+i_gsampf_d(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
const int *chans, int chan_count) {
- int ch, count, i, w;
+ int ch;
+ i_img_dim count, i, w;
unsigned char *data;
for (ch = 0; ch < chan_count; ++ch) {
if (chans[ch] < 0 || chans[ch] >= im->channels) {
=head1 SYNOPSIS
- i_img *im = i_img_double_new(int x, int y, int channels);
+ i_img *im = i_img_double_new(width, height, channels);
# use like a normal image
=head1 DESCRIPTION
#include "imager.h"
#include "imageri.h"
-static int i_ppix_ddoub(i_img *im, int x, int y, const i_color *val);
-static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val);
-static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals);
-static int i_plin_ddoub(i_img *im, int l, int r, int y, const i_color *vals);
-static int i_ppixf_ddoub(i_img *im, int x, int y, const i_fcolor *val);
-static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val);
-static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals);
-static int i_plinf_ddoub(i_img *im, int l, int r, int y, const i_fcolor *vals);
-static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
+static int i_ppix_ddoub(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
+static int i_gpix_ddoub(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
+static i_img_dim i_glin_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+static i_img_dim i_plin_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+static int i_ppixf_ddoub(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val);
+static int i_gpixf_ddoub(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val);
+static i_img_dim i_glinf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+static i_img_dim i_plinf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+static i_img_dim i_gsamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
int const *chans, int chan_count);
-static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
+static i_img_dim i_gsampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
int const *chans, int chan_count);
/*
};
/*
-=item i_img_double_new(int x, int y, int ch)
+=item i_img_double_new(i_img_dim x, i_img_dim y, int ch)
=category Image creation/destruction
=synopsis i_img *img = i_img_double_new(width, height, channels);
=cut
*/
-i_img *i_img_double_new(int x, int y, int ch) {
- int bytes;
+i_img *i_img_double_new(i_img_dim x, i_img_dim y, int ch) {
+ size_t bytes;
i_img *im;
- mm_log((1,"i_img_double_new(x %d, y %d, ch %d)\n", x, y, ch));
+ mm_log((1,"i_img_double_new(x %" i_DF ", y %" i_DF ", ch %d)\n",
+ i_DFc(x), i_DFc(y), ch));
if (x < 1 || y < 1) {
i_push_error(0, "Image sizes must be positive");
return im;
}
-static int i_ppix_ddoub(i_img *im, int x, int y, const i_color *val) {
- int off, ch;
+static int i_ppix_ddoub(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) {
- int off, ch;
+static int i_gpix_ddoub(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_ppixf_ddoub(i_img *im, int x, int y, const i_fcolor *val) {
- int off, ch;
+static int i_ppixf_ddoub(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
- int off, ch;
+static int i_gpixf_ddoub(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *val) {
+ i_img_dim off;
+ int ch;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
return 0;
}
-static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_glin_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_plin_ddoub(i_img *im, int l, int r, int y, const i_color *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_plin_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_glinf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_plinf_ddoub(i_img *im, int l, int r, int y, const i_fcolor *vals) {
- int ch, count, i;
- int off;
+static i_img_dim i_plinf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
+ int ch;
+ i_img_dim count, i;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
}
}
-static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
+static i_img_dim i_gsamp_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
int const *chans, int chan_count) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
+static i_img_dim i_gsampf_ddoub(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samps,
int const *chans, int chan_count) {
- int ch, count, i, w;
- int off;
+ int ch;
+ i_img_dim count, i, w;
+ i_img_dim off;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
i_img_to_drgb(i_img *im) {
i_img *targ;
i_fcolor *line;
- int y;
+ i_img_dim y;
targ = i_img_double_new(im->xsize, im->ysize, im->channels);
if (!targ)
void
malloc_state(void) {
- int i, total = 0;
+ int i;
+ size_t total = 0;
i_clear_error();
mm_log((0,"malloc_state()\n"));
bndcheck_all();
for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr != NULL) {
- mm_log((0,"%d: %d (0x%x) : %s\n", i, malloc_pointers[i].size, malloc_pointers[i].ptr, malloc_pointers[i].comm));
+ mm_log((0,"%d: %lu (%p) : %s\n", i, (unsigned long)malloc_pointers[i].size, malloc_pointers[i].ptr, malloc_pointers[i].comm));
total += malloc_pointers[i].size;
}
if (total == 0) mm_log((0,"No memory currently used!\n"))
- else mm_log((0,"total: %d\n",total));
+ else mm_log((0,"total: %lu\n", (unsigned long)total));
}
}
if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) {
- mm_log((1,"Unable to allocate %i for %s (%i)\n", size, file, line));
+ mm_log((1,"Unable to allocate %ld for %s (%i)\n", (long)size, file, line));
exit(3);
}
buf = set_entry(i, buf, size, file, line);
- mm_log((1,"mymalloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, size, buf, file, line));
+ mm_log((1,"mymalloc_file_line: slot <%d> %ld bytes allocated at %p for %s (%d)\n", i, (long)size, buf, file, line));
return buf;
}
void *
-(mymalloc)(int size) {
+(mymalloc)(size_t size) {
return mymalloc_file_line(size, "unknown", 0);
}
}
if ( (buf = realloc(((char *)ptr)-UNDRRNVAL, UNDRRNVAL+OVERRNVAL+newsize)) == NULL ) {
- mm_log((1,"Unable to reallocate %i bytes at %p for %s (%i)\n", newsize, ptr, file, line));
+ mm_log((1,"Unable to reallocate %ld bytes at %p for %s (%i)\n", (long)
+ newsize, ptr, file, line));
exit(3);
}
buf = set_entry(i, buf, newsize, file, line);
- mm_log((1,"realloc_file_line: slot <%d> %d bytes allocated at %p for %s (%d)\n", i, newsize, buf, file, line));
+ mm_log((1,"realloc_file_line: slot <%d> %ld bytes allocated at %p for %s (%d)\n", i, (long)newsize, buf, file, line));
return buf;
}
return;
}
- for(i=0;i<UNDRRNVAL;i++)
- if (pp[-(1+i)] != PADBYTE)
- mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
+ for(i=0;i<UNDRRNVAL;i++) {
+ if (pp[-(1+i)] != PADBYTE)
+ mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %ld\n", i+1, idx, pp, (long)s ));
+ }
- for(i=0;i<OVERRNVAL;i++)
+ for(i=0;i<OVERRNVAL;i++) {
if (pp[s+i] != PADBYTE)
- mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %d\n", i+1, idx, pp, s ));
+ mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %ld\n", i+1, idx, pp, (long)s ));
+ }
}
void
#else
-#define malloc_comm(a,b) (mymalloc(a))
-
void
malloc_state() {
}
void*
-mymalloc(int size) {
+mymalloc(size_t size) {
void *buf;
if (size < 0) {
- fprintf(stderr, "Attempt to allocate size %d\n", size);
+ fprintf(stderr, "Attempt to allocate size %ld\n", (long)size);
exit(3);
}
if ( (buf = malloc(size)) == NULL ) {
- mm_log((1, "mymalloc: unable to malloc %d\n", size));
- fprintf(stderr,"Unable to malloc %d.\n", size); exit(3);
+ mm_log((1, "mymalloc: unable to malloc %ld\n", (long)size));
+ fprintf(stderr,"Unable to malloc %ld.\n", (long)size); exit(3);
}
- mm_log((1, "mymalloc(size %d) -> %p\n", size, buf));
+ mm_log((1, "mymalloc(size %ld) -> %p\n", (long)size, buf));
return buf;
}
myrealloc(void *block, size_t size) {
void *result;
- mm_log((1, "myrealloc(block %p, size %u)\n", block, size));
+ mm_log((1, "myrealloc(block %p, size %ld)\n", block, (long)size));
if ((result = realloc(block, size)) == NULL) {
mm_log((1, "myrealloc: out of memory\n"));
fprintf(stderr, "Out of memory.\n");
Modifies *p and *len to indicate the consumed characters.
This doesn't support the extended C<UTF-8> encoding used by later
-versions of Perl.
+versions of Perl. Since this is typically used to implement text
+output by font drivers, the strings supplied shouldn't have such out
+of range characters.
This doesn't check that the C<UTF-8> character is using the shortest
possible representation.
+Returns ~0UL on failure.
+
=cut
*/
realseek_seek(io_glue *ig, off_t offset, int whence) {
/* io_ex_rseek *ier = ig->exdata; Needed later */
void *p = ig->source.cb.p;
- int rc;
+ off_t rc;
IOL_DEB( printf("realseek_seek(ig %p, offset %ld, whence %d)\n", ig, (long) offset, whence) );
rc = ig->source.cb.seekcb(p, offset, whence);
IOL_DEB( printf("buffer_read: ieb->cpos = %ld, buf = %p, count = %d\n", (long) ieb->cpos, buf, count) );
if ( ieb->cpos+count > ig->source.buffer.len ) {
- mm_log((1,"buffer_read: short read: cpos=%d, len=%d, count=%d\n", ieb->cpos, ig->source.buffer.len));
+ mm_log((1,"buffer_read: short read: cpos=%ld, len=%ld, count=%ld\n", (long)ieb->cpos, (long)ig->source.buffer.len, (long)count));
count = ig->source.buffer.len - ieb->cpos;
}
memcpy(buf, ig->source.buffer.data+ieb->cpos, count);
ieb->cpos += count;
- IOL_DEB( printf("buffer_read: count = %d\n", count) );
+ IOL_DEB( printf("buffer_read: count = %ld\n", (long)count) );
return count;
}
char *cbuf = buf;
size_t sk;
- mm_log((1, "bufchain_read(ig %p, buf %p, count %ld)\n", ig, buf, count));
+ mm_log((1, "bufchain_read(ig %p, buf %p, count %ld)\n", ig, buf, (long)count));
while( scount ) {
int clen = (ieb->cp == ieb->tail) ? ieb->tfill : ieb->cp->len;
ieb->gpos += sk;
}
- mm_log((1, "bufchain_read: returning %d\n", count-scount));
+ mm_log((1, "bufchain_read: returning %ld\n", (long)(count-scount)));
return count-scount;
}
size_t ocount = count;
size_t sk;
- mm_log((1, "bufchain_write: ig = %p, buf = %p, count = %d\n", ig, buf, count));
+ mm_log((1, "bufchain_write: ig = %p, buf = %p, count = %ld\n", ig, buf, (long)count));
- IOL_DEB( printf("bufchain_write: ig = %p, ieb->cpos = %ld, buf = %p, count = %d\n", ig, (long) ieb->cpos, buf, count) );
+ IOL_DEB( printf("bufchain_write: ig = %p, ieb->cpos = %ld, buf = %p, count = %ld\n", ig, (long) ieb->cpos, buf, (long)count) );
while(count) {
- mm_log((2, "bufchain_write: - looping - count = %d\n", count));
+ mm_log((2, "bufchain_write: - looping - count = %ld\n", (long)count));
if (ieb->cp->len == ieb->cpos) {
- mm_log((1, "bufchain_write: cp->len == ieb->cpos = %d - advancing chain\n", (long) ieb->cpos));
+ mm_log((1, "bufchain_write: cp->len == ieb->cpos = %ld - advancing chain\n", (long) ieb->cpos));
io_bchain_advance(ieb);
}
off_t scount = calc_seek_offset(ieb->gpos, ieb->length, offset, whence);
off_t sk;
- mm_log((1, "bufchain_seek(ig %p, offset %ld, whence %d)\n", ig, offset, whence));
+ mm_log((1, "bufchain_seek(ig %p, offset %ld, whence %d)\n", ig, (long)offset, whence));
if (scount < 0) {
i_push_error(0, "invalid whence supplied or seek before start of file");
while(wrlen > 0) {
ssize_t rc, wl = i_min(wrlen, BBSIZ);
- mm_log((1, "bufchain_seek: wrlen = %d, wl = %d\n", wrlen, wl));
+ mm_log((1, "bufchain_seek: wrlen = %d, wl = %ld\n", wrlen, (long)wl));
rc = bufchain_write( ig, TB, wl );
if (rc != wl) i_fatal(0, "bufchain_seek: Unable to extend file\n");
wrlen -= rc;
}
}
- mm_log((2, "bufchain_seek: returning ieb->gpos = %d\n", ieb->gpos));
+ mm_log((2, "bufchain_seek: returning ieb->gpos = %ld\n", (long)ieb->gpos));
return ieb->gpos;
}
io_glue *ig;
io_ex_buffer *ieb = mymalloc(sizeof(io_ex_buffer));
- mm_log((1, "io_new_buffer(data %p, len %d, closecb %p, closedata %p)\n", data, len, closecb, closedata));
+ mm_log((1, "io_new_buffer(data %p, len %ld, closecb %p, closedata %p)\n", data, (long)len, closecb, closedata));
ig = mymalloc(sizeof(io_glue));
memset(ig, 0, sizeof(*ig));
#endif
#include <sys/types.h>
#include <stddef.h>
+#include <stdio.h>
typedef enum { FDSEEK, FDNOSEEK, BUFFER, CBSEEK, CBNOSEEK, BUFCHAIN } io_type;
i_color black;
black.rgba.r = black.rgba.g = black.rgba.b = black.rgba.a = 0;
i_fill_t *fill;
- i_img_dim x;
+ i_img_dim x, y;
+ printf("left %" i_DF "\n", i_DFc(x));
+ printf("point (" i_DFp ")\n", i_DFcp(x, y));
# Drawing
i_arc(im, 50, 50, 20, 45, 135, &color);
=item i_img
+ i_img *img;
+
This is Imager's image type.
It contains the following members:
=item i_color
+ i_color black;
+ black.rgba.r = black.rgba.g = black.rgba.b = black.rgba.a = 0;
+
Type for 8-bit/sample color.
Samples as per;
=item i_fill_t
+ i_fill_t *fill;
+
This is the "abstract" base type for Imager's fill types.
Unless you're implementing a new fill type you'll typically treat this
=item i_img_dim
+ i_img_dim x, y;
+
A signed integer type that represents an image dimension or ordinate.
May be larger than int on some platforms.
+=for comment
+From: File imdatatypes.h
+
+=item i_DF
+
+ printf("left %" i_DF "\n", i_DFc(x));
+
+This is a constant string that can be used with functions like
+printf() to format i_img_dim values after they're been cast with i_DFc().
+
+Does not include the leading C<%>.
+
+
+=for comment
+From: File imdatatypes.h
+
+=item i_DFc
+
+Cast an C<i_img_dim> value to a type for use with the i_DF format
+string.
+
+
+=for comment
+From: File imdatatypes.h
+
+=item i_DFcp
+
+Casts two C<i_img_dim> values for use with the i_DF (or i_DFp) format.
+
+
+=for comment
+From: File imdatatypes.h
+
+=item i_DFp
+
+ printf("point (" i_DFp ")\n", i_DFcp(x, y));
+
+Format a pair of C<i_img_dim> values. This format string I<does>
+include the leading C<%>.
+
+
=for comment
From: File imdatatypes.h
=item i_arc(im, x, y, rad, d1, d2, color)
+ i_arc(im, 50, 50, 20, 45, 135, &color);
+
Fills an arc centered at (x,y) with radius I<rad> covering the range
of angles in degrees from d1 to d2, with the color.
=item i_arc_aa(im, x, y, rad, d1, d2, color)
+ i_arc_aa(im, 50, 50, 35, 90, 135, &color);
+
Anti-alias fills an arc centered at (x,y) with radius I<rad> covering
the range of angles in degrees from d1 to d2, with the color.
=item i_arc_aa_cfill(im, x, y, rad, d1, d2, fill)
+ i_arc_aa_cfill(im, 50, 50, 35, 90, 135, fill);
+
Anti-alias fills an arc centered at (x,y) with radius I<rad> covering
the range of angles in degrees from d1 to d2, with the fill object.
=item i_arc_cfill(im, x, y, rad, d1, d2, fill)
+ i_arc_cfill(im, 50, 50, 35, 90, 135, fill);
+
Fills an arc centered at (x,y) with radius I<rad> covering the range
of angles in degrees from d1 to d2, with the fill object.
=item i_box(im, x1, y1, x2, y2, color)
+ i_box(im, 0, 0, im->xsize-1, im->ysize-1, &color).
+
Outlines the box from (x1,y1) to (x2,y2) inclusive with I<color>.
=item i_box_cfill(im, x1, y1, x2, y2, fill)
+ i_box_cfill(im, 0, 0, im->xsize-1, im->ysize-1, fill);
+
Fills the box from (x1,y1) to (x2,y2) inclusive with fill.
=item i_box_filled(im, x1, y1, x2, y2, color)
+ i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &color);
+
Fills the box from (x1,y1) to (x2,y2) inclusive with color.
=item i_circle_aa(im, x, y, rad, color)
+ i_circle_aa(im, 50, 50, 45, &color);
+
Anti-alias fills a circle centered at (x,y) for radius I<rad> with
color.
=item i_flood_cfill(C<im>, C<seedx>, C<seedy>, C<fill>)
+ i_flood_cfill(im, 50, 50, fill);
+
Flood fills the 4-connected region starting from the point (C<seedx>,
C<seedy>) with C<fill>.
=item i_flood_cfill_border(C<im>, C<seedx>, C<seedy>, C<fill>, C<border>)
+ i_flood_cfill_border(im, 50, 50, fill, border);
+
Flood fills the 4-connected region starting from the point (C<seedx>,
C<seedy>) with C<fill>, the fill stops when it reaches pixels of color
C<border>.
=item i_flood_fill(C<im>, C<seedx>, C<seedy>, C<color>)
+ i_flood_fill(im, 50, 50, &color);
+
Flood fills the 4-connected region starting from the point (C<seedx>,
C<seedy>) with I<color>.
=item i_flood_fill_border(C<im>, C<seedx>, C<seedy>, C<color>, C<border>)
+ i_flood_fill_border(im, 50, 50, &color, &border);
+
Flood fills the 4-connected region starting from the point (C<seedx>,
C<seedy>) with C<color>, fill stops when the fill reaches a pixels
with color C<border>.
=item i_clear_error()
+ i_clear_error();
+
Clears the error stack.
Called by any Imager function before doing any other processing.
=item i_push_error(int code, char const *msg)
+ i_push_error(0, "Yep, it's broken");
+ i_push_error(errno, "Error writing");
+
Called by an Imager function to push an error message onto the stack.
No message is pushed if the stack is full (since this means someone
=item i_push_errorf(int code, char const *fmt, ...)
+ i_push_errorf(errno, "Cannot open file %s: %d", filename, errno);
+
A version of i_push_error() that does printf() like formatting.
Does not support perl specific format codes.
=item i_get_image_file_limits(&width, &height, &bytes)
+ i_get_image_file_limits(&width, &height, &bytes)
+
Retrieves the file limits set by i_set_image_file_limits().
+=over
+
+=item *
+
+i_img_dim *width, *height - the maximum width and height of the image.
+
+=item *
+
+size_t *bytes - size in memory of the image in bytes.
+
+=back
+
=for comment
From: File limits.c
=item i_int_check_image_file_limits(width, height, channels, sample_size)
+ i_i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))
+
Checks the size of a file in memory against the configured image file
limits.
=item i_set_image_file_limits(width, height, bytes)
+ i_set_image_file_limits(500, 500, 1000000);
+
Set limits on the sizes of images read by Imager.
Setting a limit to 0 means that limit is ignored.
Negative limits result in failure.
+Parameters:
+
+=over
+
+=item *
+
+i_img_dim width, height - maximum width and height.
+
+=item *
+
+size_t bytes - maximum size in memory in bytes
+
+=back
+
Returns non-zero on success.
=item i_new_fill_fount(C<xa>, C<ya>, C<xb>, C<yb>, C<type>, C<repeat>, C<combine>, C<super_sample>, C<ssample_param>, C<count>, C<segs>)
+ fill = i_new_fill_fount(0, 0, 100, 100, i_ft_linear, i_ft_linear,
+ i_fr_triangle, 0, i_fts_grid, 9, 1, segs);
+
Creates a new general fill which fills with a fountain fill.
=item i_new_fill_hatch(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
+ i_fill_t *fill = i_new_fill_hatch(&fg_color, &bg_color, combine, hatch, custom_hatch, dx, dy);
+
Creates a new hatched fill with the C<fg> color used for the 1 bits in
the hatch and C<bg> for the 0 bits. If C<combine> is non-zero alpha
values will be combined.
=item i_new_fill_hatchf(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
+ i_fill_t *fill = i_new_fill_hatchf(&fg_fcolor, &bg_fcolor, combine, hatch, custom_hatch, dx, dy);
+
Creates a new hatched fill with the C<fg> color used for the 1 bits in
the hatch and C<bg> for the 0 bits. If C<combine> is non-zero alpha
values will be combined.
=item i_new_fill_image(C<im>, C<matrix>, C<xoff>, C<yoff>, C<combine>)
+ i_fill_t *fill = i_new_fill_image(src_img, matrix, x_offset, y_offset, combine);
+
Create an image based fill.
matrix is an array of 9 doubles representing a transformation matrix.
=item i_new_fill_solid(color, combine)
+ i_fill_t *fill = i_new_fill_solid(&color, combine);
+
Create a solid fill based on an 8-bit color.
If combine is non-zero then alpha values will be combined.
=item i_new_fill_solidf(color, combine)
+ i_fill_t *fill = i_new_fill_solidf(&fcolor, combine);
+
Create a solid fill based on a float color.
If combine is non-zero then alpha values will be combined.
=item i_fill_destroy(fill)
+ i_fill_destroy(fill);
+
Call to destroy any fill object.
=item i_img_16_new(x, y, ch)
+ i_img *img = i_img_16_new(width, height, channels);
+
Create a new 16-bit/sample image.
Returns the image on success, or NULL on failure.
+ i_img *img = i_img_8_new(width, height, channels);
+
Creates a new image object I<x> pixels wide, and I<y> pixels high with
I<ch> channels.
=for comment
From: File img8.c
-=item i_img_double_new(int x, int y, int ch)
+=item i_img_double_new(i_img_dim x, i_img_dim y, int ch)
+
+ i_img *img = i_img_double_new(width, height, channels);
Creates a new double per sample image.
=item i_img_pal_new(C<x>, C<y>, C<channels>, C<maxpal>)
+ i_img *img = i_img_pal_new(width, height, channels, max_palette_size)
+
Creates a new paletted image of the supplied dimensions.
C<maxpal> is the maximum palette size and should normally be 256.
=item i_sametype(C<im>, C<xsize>, C<ysize>)
+ i_img *img = i_sametype(src, width, height);
+
Returns an image of the same type (sample size, channels, paletted/direct).
For paletted images the palette is copied from the source.
=item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
+ i_img *img = i_sametype_chans(src, width, height, channels);
+
Returns an image of the same type (sample size).
For paletted images the equivalent direct type is returned.
=item i_img_destroy(C<img>)
+ i_img_destroy(img)
+
Destroy an image object
=item i_img_get_height(C<im>)
+ i_img_dim height = i_img_get_height(im);
+
Returns the height in pixels of the image.
=item i_img_get_width(C<im>)
+ i_img_dim width = i_img_get_width(im);
+
Returns the width in pixels of the image.
=item i_img_getchannels(C<im>)
+ int channels = i_img_getchannels(img);
+
Get the number of channels in C<im>.
=item i_img_getmask(C<im>)
+ int mask = i_img_getmask(img);
+
Get the image channel mask for C<im>.
=item i_img_setmask(C<im>, C<ch_mask>)
+ // only channel 0 writeable
+ i_img_setmask(img, 0x01);
+
Set the image channel mask for C<im> to C<ch_mask>.
The image channel mask gives some control over which channels can be
=item i_tags_set(tags, name, data, size)
+ i_tags_set(&img->tags, "i_comment", -1);
+
Sets the given tag to the string I<data>
If size is -1 then the strlen(I<data>) bytes are stored.
=item i_tags_setn(C<tags>, C<name>, C<idata>)
+ i_tags_setn(&img->tags, "i_xres", 204);
+ i_tags_setn(&img->tags, "i_yres", 196);
+
Sets the given tag to the integer C<idata>
Even on failure, if an existing tag C<name> exists, it will be
Modifies *p and *len to indicate the consumed characters.
This doesn't support the extended C<UTF-8> encoding used by later
-versions of Perl.
+versions of Perl. Since this is typically used to implement text
+output by font drivers, the strings supplied shouldn't have such out
+of range characters.
This doesn't check that the C<UTF-8> character is using the shortest
possible representation.
+Returns ~0UL on failure.
+
=for comment
From: File io.c
You may also want to set limits on the size of the image read, using
Imager's C<set_file_limits> method, documented in
-L<Imager::Files/set_file_limits>. For example:
+L<Imager::Files/set_file_limits()>. For example:
# limit to 10 million bytes of memory usage
Imager->set_file_limits(bytes => 10_000_000);
=over
-=item set_file_limits
+=item set_file_limits()
In some cases you will be receiving images from an untested source,
such as submissions via CGI. To prevent such images from consuming
Any limit of zero is treated as unlimited.
-By default, all of the limits are zero, or unlimited.
+By default, the width and height limits are zero, or unlimited. The
+default memory size limit is one gigabyte.
-You can reset all of the limited to their defaults by passing in the
-reset parameter as a true value:
+You can reset all limits to unlimited with the reset parameter:
# no limits
Imager->set_file_limits(reset=>1);
# only bytes is limited
Imager->set_file_limits(reset=>1, bytes=>10_000_000);
-=item get_file_limits
+=item get_file_limits()
You can get the current limits with the get_file_limits() method:
#include "imageri.h"
-static int max_width, max_height;
-static int max_bytes;
+static i_img_dim max_width, max_height;
+static size_t max_bytes = 0x40000000;
/*
=item i_set_image_file_limits(width, height, bytes)
Negative limits result in failure.
+Parameters:
+
+=over
+
+=item *
+
+i_img_dim width, height - maximum width and height.
+
+=item *
+
+size_t bytes - maximum size in memory in bytes
+
+=back
+
Returns non-zero on success.
=cut
*/
int
-i_set_image_file_limits(int width, int height, int bytes) {
+i_set_image_file_limits(i_img_dim width, i_img_dim height, size_t bytes) {
i_clear_error();
if (width < 0) {
Retrieves the file limits set by i_set_image_file_limits().
+=over
+
+=item *
+
+i_img_dim *width, *height - the maximum width and height of the image.
+
+=item *
+
+size_t *bytes - size in memory of the image in bytes.
+
+=back
+
=cut
*/
int
-i_get_image_file_limits(int *width, int *height, int *bytes) {
+i_get_image_file_limits(i_img_dim *width, i_img_dim *height, size_t *bytes) {
i_clear_error();
*width = max_width;
*/
int
-i_int_check_image_file_limits(int width, int height, int channels, int sample_size) {
- int bytes;
+i_int_check_image_file_limits(i_img_dim width, i_img_dim height, int channels, size_t sample_size) {
+ size_t bytes;
i_clear_error();
if (width <= 0) {
- i_push_errorf(0, "file size limit - image width of %d is not positive",
- width);
+ i_push_errorf(0, "file size limit - image width of %" i_DF " is not positive",
+ i_DFc(width));
return 0;
}
if (max_width && width > max_width) {
- i_push_errorf(0, "file size limit - image width of %d exceeds limit of %d",
- width, max_width);
+ i_push_errorf(0, "file size limit - image width of %" i_DF " exceeds limit of %" i_DF,
+ i_DFc(width), i_DFc(max_width));
return 0;
}
if (height <= 0) {
- i_push_errorf(0, "file size limit - image height %d is not positive",
- height);
+ i_push_errorf(0, "file size limit - image height %" i_DF " is not positive",
+ i_DFc(height));
return 0;
}
if (max_height && height > max_height) {
- i_push_errorf(0, "file size limit - image height of %d "
- "exceeds limit of %d", height, max_height);
+ i_push_errorf(0, "file size limit - image height of %" i_DF
+ " exceeds limit of %" i_DF, i_DFc(height), i_DFc(max_height));
return 0;
}
}
if (sample_size < 1 || sample_size > sizeof(long double)) {
- i_push_errorf(0, "file size limit - sample_size %d out of range",
- sample_size);
+ i_push_errorf(0, "file size limit - sample_size %ld out of range",
+ (long)sample_size);
return 0;
}
}
if (max_bytes) {
if (bytes > max_bytes) {
- i_push_errorf(0, "file size limit - storage size of %d "
- "exceeds limit of %d", bytes, max_bytes);
+ i_push_errorf(0, "file size limit - storage size of %lu "
+ "exceeds limit of %lu", (unsigned long)bytes,
+ (unsigned long)max_bytes);
return 0;
}
}
#include "log.h"
#include <stdlib.h>
#include <errno.h>
+#include "imerror.h"
#ifdef IMAGER_LOG
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
+#include "imdatatypes.h"
/*
input: name of file to log too
input: onoff, 0 means no logging
int i_init_log( const char *name, int onoff );
void i_fatal ( int exitcode,const char *fmt, ... );
void i_lhead ( const char *file, int line );
-void i_loog(int level,const char *msg, ... );
+void i_loog(int level,const char *msg, ... ) I_FORMAT_ATTR(2,3);
/*
=item mm_log((level, format, ...))
void
i_map(i_img *im, unsigned char (*maps)[256], unsigned int mask) {
i_color *vals;
- int x, y;
+ i_img_dim x, y;
int i, ch;
int minset = -1, maxset = 0;
typedef struct {
i_img *targ;
i_img *mask;
- int xbase, ybase;
+ i_img_dim xbase, ybase;
i_sample_t *samps; /* temp space */
} i_img_mask_ext;
#define MASKEXT(im) ((i_img_mask_ext *)((im)->ext_data))
static void i_destroy_masked(i_img *im);
-static int i_ppix_masked(i_img *im, int x, int y, const i_color *pix);
-static int i_ppixf_masked(i_img *im, int x, int y, const i_fcolor *pix);
-static int i_plin_masked(i_img *im, int l, int r, int y, const i_color *vals);
-static int i_plinf_masked(i_img *im, int l, int r, int y, const i_fcolor *vals);
-static int i_gpix_masked(i_img *im, int x, int y, i_color *pix);
-static int i_gpixf_masked(i_img *im, int x, int y, i_fcolor *pix);
-static int i_glin_masked(i_img *im, int l, int r, int y, i_color *vals);
-static int i_glinf_masked(i_img *im, int l, int r, int y, i_fcolor *vals);
-static int i_gsamp_masked(i_img *im, int l, int r, int y, i_sample_t *samp,
+static int i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix);
+static int i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix);
+static i_img_dim i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+static i_img_dim i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals);
+static int i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix);
+static int i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix);
+static i_img_dim i_glin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+static i_img_dim i_glinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals);
+static i_img_dim i_gsamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
int const *chans, int chan_count);
-static int i_gsampf_masked(i_img *im, int l, int r, int y, i_fsample_t *samp,
+static i_img_dim i_gsampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
int const *chans, int chan_count);
-static int i_gpal_masked(i_img *im, int l, int r, int y, i_palidx *vals);
-static int i_ppal_masked(i_img *im, int l, int r, int y, const i_palidx *vals);
+static i_img_dim i_gpal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals);
+static i_img_dim i_ppal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals);
/*
=item IIM_base_masked
};
/*
-=item i_img_masked_new(i_img *targ, i_img *mask, int xbase, int ybase, int w, int h)
+=item i_img_masked_new(i_img *targ, i_img *mask, i_img_dim xbase, i_img_dim ybase, i_img_dim w, i_img_dim h)
Create a new masked image.
=cut
*/
-i_img *i_img_masked_new(i_img *targ, i_img *mask, int x, int y, int w, int h) {
+i_img *i_img_masked_new(i_img *targ, i_img *mask, i_img_dim x, i_img_dim y, i_img_dim w, i_img_dim h) {
i_img *im;
i_img_mask_ext *ext;
}
/*
-=item i_ppix_masked(i_img *im, int x, int y, const i_color *pix)
+=item i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix)
Write a pixel to a masked image.
=cut
*/
-static int i_ppix_masked(i_img *im, int x, int y, const i_color *pix) {
+static int i_ppix_masked(i_img *im, i_img_dim x, i_img_dim y, const i_color *pix) {
i_img_mask_ext *ext = MASKEXT(im);
int result;
}
/*
-=item i_ppixf_masked(i_img *im, int x, int y, const i_fcolor *pix)
+=item i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix)
Write a pixel to a masked image.
=cut
*/
-static int i_ppixf_masked(i_img *im, int x, int y, const i_fcolor *pix) {
+static int i_ppixf_masked(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
i_img_mask_ext *ext = MASKEXT(im);
int result;
}
/*
-=item i_plin_masked(i_img *im, int l, int r, int y, const i_color *vals)
+=item i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals)
Write a row of data to a masked image.
=cut
*/
-static int i_plin_masked(i_img *im, int l, int r, int y, const i_color *vals) {
+static i_img_dim i_plin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
if (ext->mask) {
- int i;
+ i_img_dim i;
int simple = 0;
i_sample_t *samps = ext->samps;
- int w = r - l;
+ i_img_dim w = r - l;
i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
if (w < 10)
else {
/* the idea is to make a fast scan to see how often the state
changes */
- int changes = 0;
+ i_img_dim changes = 0;
for (i = 0; i < w-1; ++i)
if (!samps[i] != !samps[i+1])
++changes;
/* the scan above indicates there should be some contiguous
regions, look for them and render
*/
- int start;
+ i_img_dim start;
i = 0;
while (i < w) {
while (i < w && !samps[i])
}
}
else {
- int result = i_plin(ext->targ, l + ext->xbase, r + ext->xbase,
+ i_img_dim result = i_plin(ext->targ, l + ext->xbase, r + ext->xbase,
y + ext->ybase, vals);
im->type = ext->targ->type;
return result;
}
/*
-=item i_plinf_masked(i_img *im, int l, int r, int y, const i_fcolor *vals)
+=item i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals)
Write a row of data to a masked image.
=cut
*/
-static int i_plinf_masked(i_img *im, int l, int r, int y, const i_fcolor *vals) {
+static i_img_dim i_plinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
if (ext->mask) {
- int i;
+ i_img_dim i;
int simple = 0;
i_sample_t *samps = ext->samps;
- int w = r - l;
+ i_img_dim w = r - l;
i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
if (w < 10)
else {
/* the idea is to make a fast scan to see how often the state
changes */
- int changes = 0;
+ i_img_dim changes = 0;
for (i = 0; i < w-1; ++i)
if (!samps[i] != !samps[i+1])
++changes;
/* the scan above indicates there should be some contiguous
regions, look for them and render
*/
- int start;
+ i_img_dim start;
i = 0;
while (i < w) {
while (i < w && !samps[i])
}
}
else {
- int result = i_plinf(ext->targ, l + ext->xbase, r + ext->xbase,
+ i_img_dim result = i_plinf(ext->targ, l + ext->xbase, r + ext->xbase,
y + ext->ybase, vals);
im->type = ext->targ->type;
return result;
}
/*
-=item i_gpix_masked(i_img *im, int x, int y, i_color *pix)
+=item i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix)
Read a pixel from a masked image.
=cut
*/
-static int i_gpix_masked(i_img *im, int x, int y, i_color *pix) {
+static int i_gpix_masked(i_img *im, i_img_dim x, i_img_dim y, i_color *pix) {
i_img_mask_ext *ext = MASKEXT(im);
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
}
/*
-=item i_gpixf_masked(i_img *im, int x, int y, i_fcolor *pix)
+=item i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
Read a pixel from a masked image.
=cut
*/
-static int i_gpixf_masked(i_img *im, int x, int y, i_fcolor *pix) {
+static int i_gpixf_masked(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
i_img_mask_ext *ext = MASKEXT(im);
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return i_gpixf(ext->targ, x + ext->xbase, y + ext->ybase, pix);
}
-static int i_glin_masked(i_img *im, int l, int r, int y, i_color *vals) {
+static i_img_dim i_glin_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int i_glinf_masked(i_img *im, int l, int r, int y, i_fcolor *vals) {
+static i_img_dim i_glinf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int i_gsamp_masked(i_img *im, int l, int r, int y, i_sample_t *samp,
+static i_img_dim i_gsamp_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samp,
int const *chans, int chan_count) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
}
}
-static int i_gsampf_masked(i_img *im, int l, int r, int y, i_fsample_t *samp,
+static i_img_dim i_gsampf_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
int const *chans, int chan_count) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
}
}
-static int i_gpal_masked(i_img *im, int l, int r, int y, i_palidx *vals) {
+static i_img_dim i_gpal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
}
}
-static int i_ppal_masked(i_img *im, int l, int r, int y, const i_palidx *vals) {
+static i_img_dim i_ppal_masked(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals) {
i_img_mask_ext *ext = MASKEXT(im);
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
if (r > im->xsize)
r = im->xsize;
if (ext->mask) {
- int i;
+ i_img_dim i;
i_sample_t *samps = ext->samps;
- int w = r - l;
- int start;
+ i_img_dim w = r - l;
+ i_img_dim start;
i_gsamp(ext->mask, l, r, y, samps, NULL, 1);
i = 0;
#include "imageri.h"
#define PALEXT(im) ((i_img_pal_ext*)((im)->ext_data))
-static int i_ppix_p(i_img *im, int x, int y, const i_color *val);
-static int i_gpix_p(i_img *im, int x, int y, i_color *val);
-static int i_glin_p(i_img *im, int l, int r, int y, i_color *vals);
-static int i_plin_p(i_img *im, int l, int r, int y, const i_color *vals);
-static int i_gsamp_p(i_img *im, int l, int r, int y, i_sample_t *samps, int const *chans, int chan_count);
-static int i_gpal_p(i_img *pm, int l, int r, int y, i_palidx *vals);
-static int i_ppal_p(i_img *pm, int l, int r, int y, const i_palidx *vals);
+static int i_ppix_p(i_img *im, i_img_dim x, i_img_dim y, const i_color *val);
+static int i_gpix_p(i_img *im, i_img_dim x, i_img_dim y, i_color *val);
+static i_img_dim i_glin_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals);
+static i_img_dim i_plin_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals);
+static i_img_dim i_gsamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, int const *chans, int chan_count);
+static i_img_dim i_gpal_p(i_img *pm, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals);
+static i_img_dim i_ppal_p(i_img *pm, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals);
static int i_addcolors_p(i_img *im, const i_color *color, int count);
static int i_getcolors_p(i_img *im, int i, i_color *color, int count);
static int i_colorcount_p(i_img *im);
=cut
*/
i_img *
-i_img_pal_new(int x, int y, int channels, int maxpal) {
+i_img_pal_new(i_img_dim x, i_img_dim y, int channels, int maxpal) {
i_img *im;
i_img_pal_ext *palext;
- int bytes, line_bytes;
+ size_t bytes, line_bytes;
i_clear_error();
if (maxpal < 1 || maxpal > 256) {
*/
static void i_img_rgb_convert(i_img *targ, i_img *src) {
i_color *row = mymalloc(sizeof(i_color) * targ->xsize);
- int y;
+ i_img_dim y;
for (y = 0; y < targ->ysize; ++y) {
i_glin(src, 0, src->xsize, y, row);
i_plin(targ, 0, src->xsize, y, row);
}
/*
-=item i_ppix_p(i_img *im, int x, int y, const i_color *val)
+=item i_ppix_p(i_img *im, i_img_dim x, i_img_dim y, const i_color *val)
Write to a pixel in the image.
=cut
*/
static int
-i_ppix_p(i_img *im, int x, int y, const i_color *val) {
+i_ppix_p(i_img *im, i_img_dim x, i_img_dim y, const i_color *val) {
i_palidx which;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
return -1;
}
/*
-=item i_gpix_p(i_img *im, int x, int y, i_color *val)
+=item i_gpix_p(i_img *im, i_img_dim x, i_img_dim y, i_color *val)
Retrieve a pixel, converting from a palette index to a color.
=cut
*/
-static int i_gpix_p(i_img *im, int x, int y, i_color *val) {
+static int i_gpix_p(i_img *im, i_img_dim x, i_img_dim y, i_color *val) {
i_palidx which;
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
return -1;
}
/*
-=item i_glinp(i_img *im, int l, int r, int y, i_color *vals)
+=item i_glinp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals)
Retrieve a row of pixels.
=cut
*/
-static int i_glin_p(i_img *im, int l, int r, int y, i_color *vals) {
+static i_img_dim i_glin_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_color *vals) {
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
int palsize = PALEXT(im)->count;
i_color *pal = PALEXT(im)->pal;
i_palidx *data;
- int count, i;
+ i_img_dim count, i;
if (r > im->xsize)
r = im->xsize;
data = ((i_palidx *)im->idata) + l + y * im->xsize;
}
/*
-=item i_plin_p(i_img *im, int l, int r, int y, const i_color *vals)
+=item i_plin_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals)
Write a line of color data to the image.
=cut
*/
-static int
-i_plin_p(i_img *im, int l, int r, int y, const i_color *vals) {
- int count, i;
+static i_img_dim
+i_plin_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_color *vals) {
+ i_img_dim count, i;
i_palidx *data;
i_palidx which;
if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
}
/*
-=item i_gsamp_p(i_img *im, int l, int r, int y, i_sample_t *samps, int chans, int chan_count)
+=item i_gsamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps, int chans, int chan_count)
=cut
*/
-static int i_gsamp_p(i_img *im, int l, int r, int y, i_sample_t *samps,
+static i_img_dim i_gsamp_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_sample_t *samps,
int const *chans, int chan_count) {
int ch;
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
int palsize = PALEXT(im)->count;
i_color *pal = PALEXT(im)->pal;
i_palidx *data;
- int count, i, w;
+ i_img_dim count, i, w;
if (r > im->xsize)
r = im->xsize;
data = ((i_palidx *)im->idata) + l + y * im->xsize;
}
/*
-=item i_gpal_p(i_img *im, int l, int r, int y, i_palidx *vals)
+=item i_gpal_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals)
=cut
*/
-static int i_gpal_p(i_img *im, int l, int r, int y, i_palidx *vals) {
+static i_img_dim i_gpal_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_palidx *vals) {
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
i_palidx *data;
- int i, w;
+ i_img_dim i, w;
if (r > im->xsize)
r = im->xsize;
data = ((i_palidx *)im->idata) + l + y * im->xsize;
}
/*
-=item i_ppal_p(i_img *im, int l, int r, int y, const i_palidx *vals)
+=item i_ppal_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals)
=cut
*/
-static int i_ppal_p(i_img *im, int l, int r, int y, const i_palidx *vals) {
+static i_img_dim i_ppal_p(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_palidx *vals) {
if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
i_palidx *data;
- int i, w;
+ i_img_dim i, w;
if (r > im->xsize)
r = im->xsize;
data = ((i_palidx *)im->idata) + l + y * im->xsize;
*/
void
-i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
- int y, t, ttx, tty;
+i_copyto(i_img *im, i_img *src, i_img_dim x1, i_img_dim y1, i_img_dim x2, i_img_dim y2, i_img_dim tx, i_img_dim ty) {
+ i_img_dim y, t, ttx, tty;
if (x2<x1) { t=x1; x1=x2; x2=t; }
if (y2<y1) { t=y1; y1=y2; y2=t; }
if (x1 == x2 || y1 == y2)
return; /* nothing to do */
- mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
- im, src, x1, y1, x2, y2, tx, ty));
+ mm_log((1,"i_copyto(im* %p, src %p, p1(" i_DFp "), p2(" i_DFp "), t("
+ i_DFp "))\n",
+ im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty)));
#code im->bits == i_8_bits
IM_COLOR *row = mymalloc(sizeof(IM_COLOR) * (x2-x1));
#else
i_gsampf_bg
#endif
-(i_img *im, int l, int r, int y, IM_SAMPLE_T *samples,
+(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, IM_SAMPLE_T *samples,
int out_channels, IM_COLOR const *bg) {
if (out_channels == im->channels)
return IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
switch (im->channels) {
case 2:
{
- int x;
+ i_img_dim x;
IM_SAMPLE_T *inp = samples, *outp = samples;
IM_WORK_T grey_bg = IM_ROUND(color_to_grey(bg));
- int count;
+ i_img_dim count;
count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
if (!count)
}
case 2:
{
- int x, ch;
+ i_img_dim x;
+ int ch;
IM_SAMPLE_T *inp = samples, *outp = samples;
- int count;
+ i_img_dim count;
int channels[4] = { 0, 0, 0, 1 };
count = IM_GSAMP(im, l, r, y, samples, channels, im->channels);
case 4:
{
- int x, ch;
+ i_img_dim x;
+ int ch;
IM_SAMPLE_T *inp = samples, *outp = samples;
- int count;
+ i_img_dim count;
count = IM_GSAMP(im, l, r, y, samples, NULL, im->channels);
if (!count)
if (!misnumber(*cp))
return 0;
while( (cp = gpeek(mb)) && misnumber(*cp) ) {
- *i = *i*10+(*cp-'0');
+ int work = *i*10+(*cp-'0');
+ if (work < *i) {
+ /* overflow */
+ i_push_error(0, "integer overflow");
+ return 0;
+ }
+ *i = work;
cp = gnext(mb);
}
return 1;
i_readpnm_wiol_low( mbuf *buf, int allow_incomplete) {
i_img* im;
int type;
- int width, height, maxval, channels, pcount;
+ int width, height, maxval, channels;
int rounder;
char *cp;
else if (maxval > 65535) {
i_push_errorf(0, "maxval of %d is over 65535 - invalid pnm file",
maxval);
- mm_log((1, "i_readpnm: maxval of %d is over 65535 - invalid pnm file\n"));
+ mm_log((1, "i_readpnm: maxval of %d is over 65535 - invalid pnm file\n", maxval));
return NULL;
}
} else maxval=1;
}
channels = (type == 3 || type == 6) ? 3:1;
- pcount = width*height*channels;
if (!i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))) {
mm_log((1, "i_readpnm: image size exceeds limits\n"));
write_pbm(i_img *im, io_glue *ig, int zero_is_white) {
int x, y;
i_palidx *line;
- int write_size;
+ i_img_dim write_size;
unsigned char *write_buf;
unsigned char *writep;
char header[255];
unsigned mask;
- sprintf(header, "P4\012# CREATOR: Imager\012%d %d\012",
- im->xsize, im->ysize);
+ sprintf(header, "P4\012# CREATOR: Imager\012%" i_DF " %" i_DF "\012",
+ i_DFc(im->xsize), i_DFc(im->ysize));
if (i_io_write(ig, header, strlen(header)) < 0) {
i_push_error(0, "could not write pbm header");
return 0;
static
int
write_ppm_data_8(i_img *im, io_glue *ig, int want_channels) {
- int write_size = im->xsize * want_channels;
- int buf_size = im->xsize * im->channels;
+ size_t write_size = im->xsize * want_channels;
+ size_t buf_size = im->xsize * im->channels;
unsigned char *data = mymalloc(buf_size);
- int y = 0;
+ i_img_dim y = 0;
int rc = 1;
i_color bg;
static
int
write_ppm_data_16(i_img *im, io_glue *ig, int want_channels) {
- int line_size = im->channels * im->xsize * sizeof(i_fsample_t);
- int sample_count = want_channels * im->xsize;
- int write_size = sample_count * 2;
+ size_t line_size = im->channels * im->xsize * sizeof(i_fsample_t);
+ size_t sample_count = want_channels * im->xsize;
+ size_t write_size = sample_count * 2;
i_fsample_t *line_buf = mymalloc(line_size);
i_fsample_t *samplep;
unsigned char *write_buf = mymalloc(write_size);
unsigned char *writep;
- int sample_num;
- int y = 0;
+ size_t sample_num;
+ i_img_dim y = 0;
int rc = 1;
i_fcolor bg;
else
maxval = 65535;
- sprintf(header,"P%d\n#CREATOR: Imager\n%d %d\n%d\n",
- type, im->xsize, im->ysize, maxval);
+ sprintf(header,"P%d\n#CREATOR: Imager\n%" i_DF " %" i_DF"\n%d\n",
+ type, i_DFc(im->xsize), i_DFc(im->ysize), maxval);
if (ig->writecb(ig,header,strlen(header)) != strlen(header)) {
i_push_error(errno, "could not write ppm header");
#endif
-typedef int pcord;
+typedef i_img_dim pcord;
typedef struct {
int n;
double x;
} p_slice;
-typedef struct {
- int start;
- int stop;
-} ss_pair;
-
typedef struct {
int *line; /* temporary buffer for scanline */
- int linelen; /* length of scanline */
+ i_img_dim linelen; /* length of scanline */
} ss_scanline;
static
static
void
-ss_scanline_init(ss_scanline *ss, int linelen, int linepairs) {
+ss_scanline_init(ss_scanline *ss, i_img_dim linelen, int linepairs) {
ss->line = mymalloc( sizeof(int) * linelen );
ss->linelen = linelen;
ss_scanline_reset(ss);
pcord lminx, lmaxx; /* left line min/max within y bounds in fine coords */
pcord rminx, rmaxx; /* right line min/max within y bounds in fine coords */
- int cpix; /* x-coordinate of current pixel */
+ i_img_dim cpix; /* x-coordinate of current pixel */
int thin; /* boolean for thin/thick segment */
- int startpix; /* temporary variable for "start of this interval" */
- int stoppix; /* temporary variable for "end of this interval" */
+ i_img_dim startpix; /* temporary variable for "start of this interval" */
+ i_img_dim stoppix; /* temporary variable for "end of this interval" */
/* Find the y bounds of scanline_slice */
static void
i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, scanline_flusher flusher) {
int i ,k; /* Index variables */
- int clc; /* Lines inside current interval */
+ i_img_dim clc; /* Lines inside current interval */
/* initialize to avoid compiler warnings */
pcord tempy = 0;
- int cscl = 0; /* Current scanline */
+ i_img_dim cscl = 0; /* Current scanline */
ss_scanline templine; /* scanline accumulator */
p_point *pset; /* List of points in polygon */
/* loop on intervals */
for(i=0; i<l-1; i++) {
- int startscan = i_max( coarse(pset[i].y), 0);
- int stopscan = i_min( coarse(pset[i+1].y+15), im->ysize);
+ i_img_dim startscan = i_max( coarse(pset[i].y), 0);
+ i_img_dim stopscan = i_min( coarse(pset[i+1].y+15), im->ysize);
pcord miny, maxy; /* y bounds in fine coordinates */
POLY_DEB( pcord cc = (pset[i].y + pset[i+1].y)/2 );
static void
scanline_flush_render(i_img *im, ss_scanline *ss, int y, void *ctx) {
- int x;
- int left, right;
+ i_img_dim x;
+ i_img_dim left, right;
struct poly_render_state *state = (struct poly_render_state *)ctx;
left = 0;
i_palidx *
i_quant_translate(i_quantize *quant, i_img *img) {
i_palidx *result;
- int bytes;
+ size_t bytes;
mm_log((1, "quant_translate(quant %p, img %p)\n", quant, img));
static void
makemap_addi(i_quantize *quant, i_img **imgs, int count) {
cvec *clr;
- int cnum, i, x, y, bst_idx=0, ld, cd, iter, currhb, img_num;
+ int cnum, i, bst_idx=0, ld, cd, iter, currhb, img_num;
+ i_img_dim x, y;
i_sample_t *val;
float dlt, accerr;
hashbox *hb;
i_mempool mp;
- int maxwidth = 0;
+ i_img_dim maxwidth = 0;
i_sample_t *line;
const int *sample_indices;
i_sample_t max[3]; /* maximum for each channel */
i_sample_t width[3]; /* width for each channel */
int start, size; /* beginning and size of the partition */
- int pixels; /* number of pixels represented by this partition */
+ i_img_dim pixels; /* number of pixels represented by this partition */
} medcut_partition;
/*
makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
quant_color_entry *colors;
i_mempool mp;
- int imgn, x, y, i, ch;
- int max_width;
+ int imgn, i, ch;
+ i_img_dim x, y, max_width;
i_color *line;
int color_count;
- int total_pixels;
+ i_img_dim total_pixels;
medcut_partition *parts;
int part_num;
int in, out;
if (eliminate_unused) {
i_palidx *line = mymalloc(sizeof(i_palidx) * imgs[imgn]->xsize);
- int x, y;
+ i_img_dim x, y;
memset(used, 0, sizeof(used));
for (y = 0; y < imgs[imgn]->ysize; ++y) {
#endif
static void translate_addi(i_quantize *quant, i_img *img, i_palidx *out) {
- int x, y, i, k, bst_idx = 0;
+ i_img_dim x, y, k;
+ int i, bst_idx = 0;
i_color val;
int pixdev = quant->perturb;
CF_VARS;
int mapw, maph, mapo;
int i;
errdiff_t *err;
- int errw;
+ i_img_dim errw;
int difftotal;
- int x, y, dx, dy;
+ i_img_dim x, y, dx, dy;
int bst_idx = 0;
int is_gray = is_gray_map(quant);
CF_VARS;
for (y = 0; y < img->ysize; ++y) {
for (x = 0; x < img->xsize; ++x) {
i_color val;
- long ld, cd;
errdiff_t perr;
i_gpix(img, x, y, &val);
if (img->channels < 3) {
static void prescan(i_img **imgs,int count, int cnum, cvec *clr, i_sample_t *line) {
- int i,k,j,x,y;
+ int i,k,j;
+ i_img_dim x,y;
i_sample_t *val;
const int *chans;
transparent_threshold(i_quantize *quant, i_palidx *data, i_img *img,
i_palidx trans_index)
{
- int x, y;
+ i_img_dim x, y;
i_sample_t *line = mymalloc(img->xsize * sizeof(i_sample_t));
int trans_chan = img->channels > 2 ? 3 : 1;
int mapw, maph, mapo;
int errw, *err, *errp;
int difftotal, out, error;
- int x, y, dx, dy, i;
+ i_img_dim x, y, dx, dy;
+ int i;
i_sample_t *line;
int trans_chan = img->channels > 2 ? 3 : 1;
i_palidx trans_index)
{
unsigned char *spot;
- int x, y;
+ i_img_dim x, y;
i_sample_t *line;
int trans_chan = img->channels > 2 ? 3 : 1;
if (quant->tr_orddith == od_custom)
static
void
-interleave(unsigned char *inbuffer,unsigned char *outbuffer,int rowsize,int channels) {
- int ch,ind,i;
+interleave(unsigned char *inbuffer,unsigned char *outbuffer,i_img_dim rowsize,int channels) {
+ i_img_dim ind,i;
+ int ch;
i=0;
if (inbuffer == outbuffer) return; /* Check if data is already in interleaved format */
for (ind=0; ind<rowsize; ind++)
static
void
expandchannels(unsigned char *inbuffer, unsigned char *outbuffer,
- int xsize, int datachannels, int storechannels) {
- int x, ch;
+ i_img_dim xsize, int datachannels, int storechannels) {
+ i_img_dim x;
+ int ch;
int copy_chans = storechannels > datachannels ? datachannels : storechannels;
if (inbuffer == outbuffer)
return; /* Check if data is already in expanded format */
}
i_img *
-i_readraw_wiol(io_glue *ig, int x, int y, int datachannels, int storechannels, int intrl) {
+i_readraw_wiol(io_glue *ig, i_img_dim x, i_img_dim y, int datachannels, int storechannels, int intrl) {
i_img* im;
- int rc,k;
+ ssize_t rc;
+ i_img_dim k;
unsigned char *inbuffer;
unsigned char *ilbuffer;
unsigned char *exbuffer;
- int inbuflen,ilbuflen,exbuflen;
+ size_t inbuflen,ilbuflen,exbuflen;
i_clear_error();
io_glue_commit_types(ig);
- mm_log((1, "i_readraw(ig %p,x %d,y %d,datachannels %d,storechannels %d,intrl %d)\n",
- ig, x, y, datachannels, storechannels, intrl));
+ mm_log((1, "i_readraw(ig %p,x %" i_DF ",y %" i_DF ",datachannels %d,storechannels %d,intrl %d)\n",
+ ig, i_DFc(x), i_DFc(y), datachannels, storechannels, intrl));
if (intrl != 0 && intrl != 1) {
i_push_error(0, "raw_interleave must be 0 or 1");
ilbuflen = inbuflen;
exbuflen = im->xsize*storechannels;
inbuffer = (unsigned char*)mymalloc(inbuflen);
- mm_log((1,"inbuflen: %d, ilbuflen: %d, exbuflen: %d.\n",inbuflen,ilbuflen,exbuflen));
+ mm_log((1,"inbuflen: %ld, ilbuflen: %ld, exbuflen: %ld.\n",
+ (long)inbuflen, (long)ilbuflen, (long)exbuflen));
if (intrl==0) ilbuffer = inbuffer;
else ilbuffer=mymalloc(inbuflen);
undef_int
i_writeraw_wiol(i_img* im, io_glue *ig) {
- int rc;
+ ssize_t rc;
io_glue_commit_types(ig);
i_clear_error();
if (im->type == i_direct_type) {
/* just save it as 8-bits, maybe support saving higher bit count
raw images later */
- int line_size = im->xsize * im->channels;
+ size_t line_size = im->xsize * im->channels;
unsigned char *data = mymalloc(line_size);
- int y = 0;
+ i_img_dim y = 0;
rc = line_size;
while (rc == line_size && y < im->ysize) {
i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
/* paletted image - assumes the caller puts the palette somewhere
else
*/
- int line_size = sizeof(i_palidx) * im->xsize;
+ size_t line_size = sizeof(i_palidx) * im->xsize;
i_palidx *data = mymalloc(sizeof(i_palidx) * im->xsize);
- int y = 0;
+ i_img_dim y = 0;
rc = line_size;
while (rc == line_size && y < im->ysize) {
i_gpal(im, 0, im->xsize, y, data);
It isn't currently used for inequalities
*/
-#define n_epsilon(x, y) (abs(x)+abs(y))*0.001
+#define n_epsilon(x, y) (fabs(x)+fabs(y))*0.001
static i_color bcol = {{ 0 }};
i_color i_rm_run(struct rm_op codes[], size_t code_count,
break;
case rbc_div:
- if (abs(nb) < 1e-10)
+ if (fabs(nb) < 1e-10)
nout = 1e10;
else
nout = na / nb;
break;
case rbc_mod:
- if (abs(nb) > 1e-10) {
+ if (fabs(nb) > 1e-10) {
nout = fmod(na, nb);
}
else {
break;
case rbc_eq:
- nout = abs(na-nb) <= n_epsilon(na,nb);
+ nout = fabs(na-nb) <= n_epsilon(na,nb);
break;
case rbc_ne:
- nout = abs(na-nb) > n_epsilon(na,nb);
+ nout = fabs(na-nb) > n_epsilon(na,nb);
break;
case rbc_and:
break;
case rbc_abs:
- nout = abs(na);
+ nout = fabs(na);
break;
case rbc_ret:
#/code
}
+#if 0
+
+/* for debuggin */
+
static void
dump_src(const char *note, unsigned char const *src, i_img_dim width) {
i_img_dim i;
- printf("%s - %p/%d\n", note, src, width);
+ printf("%s - %p/%" i_DF "\n", note, src, i_DFc(width));
for (i = 0; i < width; ++i) {
printf("%02x ", src[i]);
}
putchar('\n');
}
+#endif
+
#code
/*
i_img *i_rotate90(i_img *src, int degrees) {
i_img *targ;
- int x, y;
+ i_img_dim x, y;
i_clear_error();
return targ;
}
else if (degrees == 270 || degrees == 90) {
- int tx, txstart, txinc;
- int ty, tystart, tyinc;
+ i_img_dim tx, txstart, txinc;
+ i_img_dim ty, tystart, tyinc;
if (degrees == 270) {
txstart = 0;
return out;
}
-i_img *i_matrix_transform_bg(i_img *src, int xsize, int ysize, const double *matrix,
+i_img *i_matrix_transform_bg(i_img *src, i_img_dim xsize, i_img_dim ysize, const double *matrix,
const i_color *backp, const i_fcolor *fbackp) {
i_img *result = i_sametype(src, xsize, ysize);
- int x, y;
+ i_img_dim x, y;
int ch;
- int i, j;
+ i_img_dim i, j;
double sx, sy, sz;
if (src->type == i_direct_type) {
&& sx >= -1 && sx < src->xsize
&& sy >= -1 && sy < src->ysize) {
- if (sx != (int)sx) {
- if (sy != (int)sy) {
+ if (sx != (i_img_dim)sx) {
+ if (sy != (i_img_dim)sy) {
i_color c[2][2];
i_color ci2[2];
for (i = 0; i < 2; ++i)
}
}
else {
- if (sy != (int)sy) {
+ if (sy != (i_img_dim)sy) {
i_color ci2[2];
for (i = 0; i < 2; ++i)
if (i_gpix(src, sx, floor(sy)+i, ci2+i))
&& sx >= -1 && sx < src->xsize
&& sy >= -1 && sy < src->ysize) {
- if (sx != (int)sx) {
- if (sy != (int)sy) {
+ if (sx != (i_img_dim)sx) {
+ if (sy != (i_img_dim)sy) {
i_fcolor c[2][2];
i_fcolor ci2[2];
for (i = 0; i < 2; ++i)
}
}
else {
- if (sy != (int)sy) {
+ if (sy != (i_img_dim)sy) {
i_fcolor ci2[2];
for (i = 0; i < 2; ++i)
if (i_gpixf(src, sx, floor(sy)+i, ci2+i))
i_palidx back = 0;
i_color min;
int minval = 256 * 4;
- int ix, iy;
+ i_img_dim ix, iy;
i_color want_back;
i_fsample_t fsamp;
&& sy >= -0.5 && sy < src->ysize-0.5) {
/* all the world's an integer */
- ix = (int)(sx+0.5);
- iy = (int)(sy+0.5);
+ ix = (i_img_dim)(sx+0.5);
+ iy = (i_img_dim)(sy+0.5);
if (!i_gpal(src, ix, ix+1, iy, vals+x))
vals[i] = back;
}
return result;
}
-i_img *i_matrix_transform(i_img *src, int xsize, int ysize, const double *matrix) {
+i_img *i_matrix_transform(i_img *src, i_img_dim xsize, i_img_dim ysize, const double *matrix) {
return i_matrix_transform_bg(src, xsize, ysize, matrix, NULL, NULL);
}
double rotate[9];
double xlate2[9] = { 0 };
double temp[9], matrix[9];
- int x1, x2, y1, y2, newxsize, newysize;
+ i_img_dim x1, x2, y1, y2, newxsize, newysize;
/* first translate the centre of the image to (0,0) */
xlate1[0] = 1;
rotate[7] = 0;
rotate[8] = 1;
- x1 = ceil(abs(src->xsize * rotate[0] + src->ysize * rotate[1]));
- x2 = ceil(abs(src->xsize * rotate[0] - src->ysize * rotate[1]));
- y1 = ceil(abs(src->xsize * rotate[3] + src->ysize * rotate[4]));
- y2 = ceil(abs(src->xsize * rotate[3] - src->ysize * rotate[4]));
+ x1 = ceil(i_abs(src->xsize * rotate[0] + src->ysize * rotate[1]));
+ x2 = ceil(i_abs(src->xsize * rotate[0] - src->ysize * rotate[1]));
+ y1 = ceil(i_abs(src->xsize * rotate[3] + src->ysize * rotate[4]));
+ y2 = ceil(i_abs(src->xsize * rotate[3] - src->ysize * rotate[4]));
newxsize = x1 > x2 ? x1 : x2;
newysize = y1 > y2 ? y1 : y2;
/* translate the centre back to the center of the image */
static int
rubthru_targ_noalpha(i_img *im, i_img *src,
- int tx, int ty,
- int src_minx, int src_miny,
- int src_maxx, int src_maxy) {
- int x, y, ttx, tty;
+ 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) {
+ i_img_dim x, y, ttx, tty;
int alphachan;
int ch;
- int width = src_maxx - src_minx;
+ i_img_dim width = src_maxx - src_minx;
int want_channels;
i_clear_error();
}
static int
-rubthru_targ_alpha(i_img *im, i_img *src, int tx, int ty,
- int src_minx, int src_miny,
- int src_maxx, int src_maxy) {
- int x, y, ttx, tty;
+rubthru_targ_alpha(i_img *im, i_img *src, 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) {
+ i_img_dim x, y, ttx, tty;
int want_channels;
int alphachan;
int ch;
int targ_alpha_chan;
- int width = src_maxx - src_minx;
+ i_img_dim width = src_maxx - src_minx;
if (im->channels == 4 && (src->channels == 4 || src->channels == 2)) {
alphachan = 3;
tty = ty;
for(y = src_miny; y < src_maxy; y++) {
- int min_x, max_x;
+ i_img_dim min_x, max_x;
IM_COLOR *srcp = src_line;
IM_COLOR *destp = dest_line;
IM_GLIN(src, src_minx, src_maxx, y, src_line);
}
if (max_x > min_x) {
- int work_left = tx + min_x - src_minx;
- int work_width = max_x - min_x;
+ i_img_dim work_left = tx + min_x - src_minx;
+ i_img_dim work_width = max_x - min_x;
ttx = work_left;
IM_GLIN(im, work_left, work_left + work_width, tty, dest_line);
*/
int
-i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
- int src_maxx, int src_maxy) {
+i_rubthru(i_img *im, i_img *src, 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) {
if (src_minx < 0) {
tx -= src_minx;
src_minx = 0;
static void
-zero_row(i_fcolor *row, int width, int channels);
+zero_row(i_fcolor *row, i_img_dim width, int channels);
#code
static void
IM_SUFFIX(accum_output_row)(i_fcolor *accum, double fraction, IM_COLOR const *in,
- int width, int channels);
+ i_img_dim width, int channels);
static void
-IM_SUFFIX(horizontal_scale)(IM_COLOR *out, int out_width,
- i_fcolor const *in, int in_width,
+IM_SUFFIX(horizontal_scale)(IM_COLOR *out, i_img_dim out_width,
+ i_fcolor const *in, i_img_dim in_width,
int channels);
#/code
=cut
*/
i_img *
-i_scale_mixing(i_img *src, int x_out, int y_out) {
+i_scale_mixing(i_img *src, i_img_dim x_out, i_img_dim y_out) {
i_img *result;
i_fcolor *accum_row = NULL;
- int x, y, ch;
- int accum_row_bytes;
+ i_img_dim x, y;
+ int ch;
+ size_t accum_row_bytes;
double rowsleft, fracrowtofill;
- int rowsread;
+ i_img_dim rowsread;
double y_scale;
- mm_log((1, "i_scale_mixing(src %p, x_out %d, y_out %d)\n",
- src, x_out, y_out));
+ mm_log((1, "i_scale_mixing(src %p, out(" i_DFp "))\n",
+ src, i_DFcp(x_out, y_out)));
i_clear_error();
if (x_out <= 0) {
- i_push_errorf(0, "output width %d invalid", x_out);
+ i_push_errorf(0, "output width %" i_DF " invalid", i_DFc(x_out));
return NULL;
}
if (y_out <= 0) {
- i_push_errorf(0, "output height %d invalid", y_out);
+ i_push_errorf(0, "output height %" i_DF " invalid", i_DFc(y_out));
return NULL;
}
#code src->bits <= 8
IM_COLOR *in_row = NULL;
IM_COLOR *xscale_row = NULL;
- int in_row_bytes, out_row_bytes;
+ size_t in_row_bytes, out_row_bytes;
in_row_bytes = sizeof(IM_COLOR) * src->xsize;
if (in_row_bytes / sizeof(IM_COLOR) != src->xsize) {
if (y_out == src->ysize) {
/* no vertical scaling, just load it */
#ifdef IM_EIGHT_BIT
- int x, ch;
+ i_img_dim x;
+ int ch;
/* load and convert to doubles */
IM_GLIN(src, 0, src->xsize, y, in_row);
for (x = 0; x < src->xsize; ++x) {
/* we've accumulated a vertically scaled row */
if (x_out == src->xsize) {
#if IM_EIGHT_BIT
- int x, ch;
+ i_img_dim x;
+ int ch;
/* no need to scale, but we need to convert it */
if (result->channels == 2 || result->channels == 4) {
int alpha_chan = result->channels - 1;
}
static void
-zero_row(i_fcolor *row, int width, int channels) {
- int x;
+zero_row(i_fcolor *row, i_img_dim width, int channels) {
+ i_img_dim x;
int ch;
/* with IEEE floats we could just use memset() but that's not
static void
IM_SUFFIX(accum_output_row)(i_fcolor *accum, double fraction, IM_COLOR const *in,
- int width, int channels) {
- int x, ch;
+ i_img_dim width, int channels) {
+ i_img_dim x;
+ int ch;
/* it's tempting to change this into a pointer iteration loop but
modern CPUs do the indexing as part of the instruction */
}
static void
-IM_SUFFIX(horizontal_scale)(IM_COLOR *out, int out_width,
- i_fcolor const *in, int in_width,
+IM_SUFFIX(horizontal_scale)(IM_COLOR *out, i_img_dim out_width,
+ i_fcolor const *in, i_img_dim in_width,
int channels) {
double frac_col_to_fill, frac_col_left;
- int in_x;
- int out_x;
+ i_img_dim in_x;
+ i_img_dim out_x;
double x_scale = (double)out_width / in_width;
int ch;
double accum[MAXCHANNELS] = { 0 };
SKIP:
{
use Config;
- skip("don't want to allocate 4Gb", 8) unless $Config{intsize} == 4;
+ skip("don't want to allocate 4Gb", 8) unless $Config{ptrsize} == 4;
my $uint_range = 256 ** $Config{intsize};
print "# range $uint_range\n";
# type of exit
SKIP: {
use Config;
- $Config{intsize} == 4
- or skip("don't want to allocate 4Gb", 8);
+ $Config{ptrsize} == 4
+ or skip("don't want to allocate 4Gb", 10);
my $uint_range = 256 ** $Config{intsize};
print "# range $uint_range\n";
my $dim1 = int(sqrt($uint_range/2))+1;
use Config;
SKIP:
{
- $Config{intsize} == 4
+ $Config{ptrsize} == 4
or skip "don't want to allocate 4Gb", 8;
my $uint_range = 256 ** $Config{intsize};
my $dbl_size = $Config{doublesize} || 8;
SKIP:
{
skip("don't want to allocate 4Gb", 10)
- unless $Config{intsize} == 4;
+ unless $Config{ptrsize} == 4;
my $uint_range = 256 ** $Config{intsize};
my $dim1 = int(sqrt($uint_range))+1;
# test the scanline allocation check
# divide by 2 to get int range, by 3 so that the image (one byte/pixel)
# doesn't integer overflow, but the scanline of i_color (4/pixel) does
- my $dim4 = $uint_range / 2 / 3;
+ my $dim4 = $uint_range / 3;
my $im_o = Imager->new(xsize=>$dim4, ysize=>1, channels=>3, type=>'paletted');
is($im_o, undef, "integer overflow check - scanline size");
cmp_ok(Imager->errstr, '=~',
# test the file limit functions
# by default the limits are zero (unlimited)
print "# image file limits\n";
-is_deeply([ Imager->get_file_limits() ], [0, 0, 0],
+is_deeply([ Imager->get_file_limits() ], [0, 0, 0x40000000 ],
"check defaults");
ok(Imager->set_file_limits(width=>100), "set only width");
-is_deeply([ Imager->get_file_limits() ], [100, 0, 0 ],
+is_deeply([ Imager->get_file_limits() ], [100, 0, 0x40000000 ],
"check width set");
ok(Imager->set_file_limits(height=>150, bytes=>10000),
"set height and bytes");
#!perl -w
use Imager ':all';
-use Test::More tests => 191;
+use Test::More tests => 195;
use strict;
use Imager::Test qw(test_image_raw test_image_16 is_color3 is_color1 is_image);
Imager->close_log;
+{ # image too large handling
+ {
+ ok(!Imager->new(file => "testimg/toowide.ppm", filetype => "pnm"),
+ "fail to read a too wide image");
+ is(Imager->errstr, "unable to read pnm image: could not read image width: integer overflow",
+ "check error message");
+ }
+ {
+ ok(!Imager->new(file => "testimg/tootall.ppm", filetype => "pnm"),
+ "fail to read a too wide image");
+ is(Imager->errstr, "unable to read pnm image: could not read image height: integer overflow",
+ "check error message");
+ }
+}
+
unless ($ENV{IMAGER_KEEP_FILES}) {
unlink "testout/t104ppm.log";
unlink map "testout/$_", @files;
'bad compression (24-bit)' ],
);
use Config;
-my $intsize = $Config{intsize};
+my $ptrsize = $Config{ptrsize};
for my $test (@tests) {
my ($file, $error, $comment, $bit32only) = @$test;
SKIP:
{
skip("only tested on 32-bit machines", 2)
- if $bit32only && $intsize != 4;
+ if $bit32only && $ptrsize != 4;
ok(!$imoo->read(file=>"testimg/$file"), $comment);
+ print "# ", $imoo->errstr, "\n";
is($imoo->errstr, $error, "check error message");
}
}
#!perl -w
use Imager qw(:all);
use strict;
-use Test::More tests=>46;
+use Test::More tests=>66;
use Imager::Test qw(is_color4 is_image);
-d "testout" or mkdir "testout";
is_image($im, $im2, "check they match");
}
+{ # prior to the types re-work we treated the tga xsize/ysize as
+ # signed short, which is wrong
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 40960, ysize => 1);
+ my $data;
+ ok($im->write(data => \$data, type => "tga"),
+ "write a wide (but not too wide) image out");
+ my $im2 = Imager->new(data => $data);
+ ok($im2, "read it back in")
+ or skip("Couldn't read the wide image", 2);
+ is($im2->getwidth, 40960, "make sure the width survived the trip");
+ is($im2->getheight, 1, "make sure the height survived the trip");
+ }
+
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 1, ysize => 40960);
+ my $data;
+ ok($im->write(data => \$data, type => "tga"),
+ "write a tall (but not too tall) image out");
+ my $im2 = Imager->new(data => $data);
+ ok($im2, "read it back in")
+ or skip("Couldn't read the tall image", 2);
+ is($im2->getwidth, 1, "make sure the width survived the trip");
+ is($im2->getheight, 40960, "make sure the height survived the trip");
+ }
+}
+
+{
+ # TGA files are limited to 0xFFFF x 0xFFFF pixels
+ my $max_dim = 0xFFFF;
+ {
+ my $im = Imager->new(xsize => 1+$max_dim, ysize => 1);
+ my $data = '';
+ ok(!$im->write(data => \$data, type => "tga"),
+ "fail to write too wide an image");
+ is($im->errstr, "image too large for TGA",
+ "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 => "tga"),
+ "write image at width limit")
+ or print "# ", $im->errstr, "\n";
+ my $im2 = Imager->new(data => $data, ftype => "tga");
+ 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 => "tga"),
+ "fail to write too tall an image");
+ is($im->errstr, "image too large for TGA",
+ "check error message");
+ }
+ SKIP:
+ {
+ my $im = Imager->new(xsize => 1, ysize => $max_dim);
+ $im->box(fill => { hatch => "check2x2" });
+ my $data = '';
+ ok($im->write(data => \$data, type => "tga"),
+ "write image at width limit");
+ my $im2 = Imager->new(data => $data, ftype => "tga");
+ ok($im2, "read it ok")
+ or skip("cannot load the wide image", 1);
+ is($im->getwidth, 1, "check width");
+ is($im->getheight, $max_dim, "check height");
+ }
+}
+
sub write_test {
my ($im, $filename, $wierdpack, $compress, $idstring) = @_;
local *FH;
my $work = $rot->convert(preset => 'noalpha');
my $im_pal = $work->to_paletted(make_colors => 'mediancut');
my @colors = $im_pal->getcolors;
- is(@colors, 2, "should be only 2 colors");
+ is(@colors, 2, "should be only 2 colors")
+ or do {
+ print "# ", join(",", $_->rgba), "\n" for @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");
--- /dev/null
+P6
+1
+999999999999999999999999999999999999999999999999999999999999999999999999999999
+65535
+# we don't get this far
\ No newline at end of file
--- /dev/null
+P6
+999999999999999999999999999999999999999999999999999999999999999999999999999999
+1
+65535
+# we don't get this far
\ No newline at end of file
char colourmapdepth;
short int x_origin;
short int y_origin;
- short width;
- short height;
+ int width;
+ int height;
char bitsperpixel;
char imagedescriptor;
} tga_header;
typedef struct {
int compressed;
- int bytepp;
+ size_t bytepp;
rle_state state;
unsigned char cval[4];
int len;
io_glue *ig;
} tga_dest;
-
+#define TGA_MAX_DIM 0xFFFF
/*
=item bpp_to_bytes(bpp)
static
-int
+size_t
bpp_to_bytes(unsigned int bpp) {
switch (bpp) {
case 8:
int
tga_palette_write(io_glue *ig, i_img *img, int bitspp, int colourmaplength) {
int i;
- int bytepp = bpp_to_bytes(bitspp);
+ size_t bytepp = bpp_to_bytes(bitspp);
size_t palbsize = i_colorcount(img)*bytepp;
unsigned char *palbuf = mymalloc(palbsize);
mm_log((1,"Descriptor: %d\n",header.imagedescriptor));
if (header.idlength) {
+ /* max of 256, so this is safe */
idstring = mymalloc(header.idlength+1);
if (ig->readcb(ig, idstring, header.idlength) != header.idlength) {
i_push_error(errno, "short read on targa idstring");
}
/* Allocate buffers */
+ /* width is max 0xffff, src.bytepp is max 4, so this is safe */
databuf = mymalloc(width*src.bytepp);
+ /* similarly here */
if (!mapped) linebuf = mymalloc(width*sizeof(i_color));
for(y=0; y<height; y++) {
idlen = strlen(idstring);
mapped = img->type == i_palette_type;
- mm_log((1,"i_writetga_wiol(img %p, ig %p, idstring %p, idlen %d, wierdpack %d, compress %d)\n",
- img, ig, idstring, idlen, wierdpack, compress));
+ mm_log((1,"i_writetga_wiol(img %p, ig %p, idstring %p, idlen %ld, wierdpack %d, compress %d)\n",
+ img, ig, idstring, (long)idlen, wierdpack, compress));
mm_log((1, "virtual %d, paletted %d\n", img->virtual, mapped));
mm_log((1, "channels %d\n", img->channels));
i_clear_error();
- io_glue_commit_types(ig);
+
+ if (img->xsize > TGA_MAX_DIM || img->ysize > TGA_MAX_DIM) {
+ i_push_error(0, "image too large for TGA");
+ return 0;
+ }
switch (img->channels) {
case 1:
}
} else { /* direct type */
int x, y;
- int bytepp = wierdpack ? 2 : bpp_to_bytes(bitspp);
- int lsize = bytepp * img->xsize;
+ size_t bytepp = wierdpack ? 2 : bpp_to_bytes(bitspp);
+ size_t lsize = bytepp * img->xsize;
i_color *vals = mymalloc(img->xsize*sizeof(i_color));
unsigned char *buf = mymalloc(lsize);
=cut
*/
-i_img* i_transform2(int width, int height, int channels,
+i_img* i_transform2(i_img_dim width, i_img_dim height, int channels,
struct rm_op *ops, int ops_count,
double *n_regs, int n_regs_count,
i_color *c_regs, int c_regs_count,
i_img **in_imgs, int in_imgs_count)
{
i_img *new_img;
- int x, y;
+ i_img_dim x, y;
i_color val;
int i;
int need_images;
# mostly intended for non-Imager-core use
Imager T_IMAGER_FULL_IMAGE
+off_t T_OFF_T
+
#############################################################################
INPUT
T_PTR_NULL
else
croak(\"$var is not of type ${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\");
+T_OFF_T
+ $var = i_sv_off_t(aTHX_ $arg);
#############################################################################
OUTPUT
else {
$arg = &PL_sv_undef;
}
+T_OFF_T
+ $arg = i_new_sv_off_t(aTHX_ $var);