#include "image.h"
#include "imagei.h"
-#include "io.h"
/*
=head1 NAME
i_img *
i_img_empty_ch(i_img *im,int x,int y,int ch) {
+ int bytes;
+
mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
+
+ if (x < 1 || y < 1) {
+ i_push_error(0, "Image sizes must be positive");
+ return NULL;
+ }
+ if (ch < 1 || ch > MAXCHANNELS) {
+ i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
+ return NULL;
+ }
+ /* check this multiplication doesn't overflow */
+ bytes = x*y*ch;
+ if (bytes / y / ch != x) {
+ i_push_errorf(0, "integer overflow calculating image allocation");
+ return NULL;
+ }
+
if (im == NULL)
if ( (im=mymalloc(sizeof(i_img))) == NULL)
m_fatal(2,"malloc() error\n");
im->ysize = y;
im->channels = ch;
im->ch_mask = MAXINT;
- im->bytes=x*y*im->channels;
- if ( (im->idata=mymalloc(im->bytes)) == NULL) m_fatal(2,"malloc() error\n");
+ im->bytes=bytes;
+ if ( (im->idata=mymalloc(im->bytes)) == NULL)
+ m_fatal(2,"malloc() error\n");
memset(im->idata,0,(size_t)im->bytes);
im->ext_data = NULL;
/*
-=item i_rubthru(im, src, tx, ty)
+=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
-Takes the image I<src> and applies it at an original (I<tx>,I<ty>) in I<im>.
+Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
+overlays it at (I<tx>,I<ty>) on the image object.
The alpha channel of each pixel in I<src> is used to control how much
the existing colour in I<im> is replaced, if it is 255 then the colour
*/
int
-i_rubthru(i_img *im,i_img *src,int tx,int ty) {
+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 x, y, ttx, tty;
int chancount;
int chans[3];
int alphachan;
int ch;
- mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d)\n", im, src, tx, ty));
+ mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
+ "src_miny %d, src_maxx %d, src_maxy %d)\n",
+ im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
i_clear_error();
if (im->channels == 3 && src->channels == 4) {
changed in a similar fashion - TC */
int alpha;
i_color pv, orig, dest;
- ttx = tx;
- for(x=0; x<src->xsize; x++) {
- tty=ty;
- for(y=0;y<src->ysize;y++) {
- /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
+ tty = ty;
+ for(y = src_miny; y < src_maxy; y++) {
+ ttx = tx;
+ for(x = src_minx; x < src_maxx; x++) {
i_gpix(src, x, y, &pv);
i_gpix(im, ttx, tty, &orig);
alpha = pv.channel[alphachan];
+ (255 - alpha) * orig.channel[ch])/255;
}
i_ppix(im, ttx, tty, &dest);
- tty++;
+ ttx++;
}
- ttx++;
+ tty++;
}
}
else {
double alpha;
i_fcolor pv, orig, dest;
- ttx = tx;
- for(x=0; x<src->xsize; x++) {
- tty=ty;
- for(y=0;y<src->ysize;y++) {
- /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
+ tty = ty;
+ for(y = src_miny; y < src_maxy; y++) {
+ ttx = tx;
+ for(x = src_minx; x < src_maxx; x++) {
i_gpixf(src, x, y, &pv);
i_gpixf(im, ttx, tty, &orig);
alpha = pv.channel[alphachan];
for (ch = 0; ch < chancount; ++ch) {
dest.channel[ch] = alpha * pv.channel[chans[ch]]
- + (1 - alpha) * orig.channel[ch];
+ + (1 - alpha) * orig.channel[ch];
}
i_ppixf(im, ttx, tty, &dest);
- tty++;
+ ttx++;
}
- ttx++;
+ tty++;
}
}
}
-
-
-
-
-
-
-
-i_img*
-i_scaleaxis_3ch_8bit(i_img *im, int size, int Axis) {
-
- int i, j;
- int iEnd, jEnd;
-
- int hsize, vsize;
-
- short psave;
- unsigned long *pixels;
- i_color val;
- i_img *new_img;
-
- mm_log((1,"i_scaleaxis_3ch_8bit(im %p, size %d,Axis %d)\n",im, size, Axis));
-
- if (Axis == XAXIS) {
- hsize = size;
- vsize = im->ysize;
-
- jEnd = hsize;
- iEnd = vsize;
- pixels = mymalloc(sizeof(*pixels) * im->xsize);
- } else {
- hsize = im->xsize;
- vsize = size;
-
- jEnd = vsize;
- iEnd = hsize;
- pixels = mymalloc(sizeof(*pixels) * im->ysize);
- }
-
- new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
-
-
- if (Axis == XAXIS) {
-
- for (i=0; i<iEnd; i++) {
- int end = im->xsize;
-
- for(j=0; j<im->xsize; j++) {
- i_gpix(im, j, i, &val);
- pixels[j] = (val.rgba.r<<24) | (val.rgba.g<<16) | (val.rgba.b<<8) | (val.rgba.a<<0);
- }
-
- /* printf("jEnd = %d, end = %d\n", jEnd, end); */
- while ((end+1)/2>=size) {
- int lend = end/2;
- end = (end+1) / 2;
-
- for(j=0; j<lend; j++) {
- unsigned long a = pixels[2*j];
- unsigned long b = pixels[2*j+1];
- pixels[j] = (((a ^ b) & 0xfefefefeUL) >> 1) + (a & b);
- }
- if (end>lend) {
- pixels[j] = pixels[2*j];
- j++;
- }
- }
-
- printf("end = %d size = %d\n", end, size);
-
- /* Replace this with Bresenham later */
- for(j=0; j<size; j++) {
- float f = i;
- /* if ((i*size)/end <) */
- unsigned long t = pixels[j];
- val.rgba.r = (t >> 24) & 0xff;
- val.rgba.g = (t >> 16) & 0xff;
- val.rgba.b = (t >> 8) & 0xff;
- val.rgba.a = t & 0xff;
- i_ppix(new_img, j, i, &val);
- }
- }
- }
-
- return new_img;
-}
-
-
-
-
-
-
-
/*
=item i_scaleaxis(im, value, axis)
if (Axis == XAXIS) {
- return i_scaleaxis_3ch_8bit(im, (int)(0.5+im->xsize*Value), Axis);
-
hsize = (int)(0.5 + im->xsize * Value);
+ if (hsize < 1) {
+ hsize = 1;
+ Value = 1.0 / im->xsize;
+ }
vsize = im->ysize;
jEnd = hsize;
hsize = im->xsize;
vsize = (int)(0.5 + im->ysize * Value);
+ if (vsize < 1) {
+ vsize = 1;
+ Value = 1.0 / im->ysize;
+ }
+
jEnd = vsize;
iEnd = hsize;
}
mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
nxsize = (int) ((float) im->xsize * scx);
+ if (nxsize < 1) {
+ nxsize = 1;
+ scx = 1 / im->xsize;
+ }
nysize = (int) ((float) im->ysize * scy);
+ if (nysize < 1) {
+ nysize = 1;
+ scy = 1 / im->ysize;
+ }
new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
return result;
}
+
+
+/*
+=item i_test_format_probe(io_glue *data, int length)
+
+Check the beginning of the supplied file for a 'magic number'
+
+=cut
+*/
+
+
+char *
+i_test_format_probe(io_glue *data, int length) {
+
+ static struct {
+ char *magic;
+ char *name;
+ } formats[] = {
+ {"\xFF\xD8", "jpeg"},
+ {"GIF87a", "gif"},
+ {"GIF89a", "gif"},
+ {"MM\0*", "tiff"},
+ {"II*\0", "tiff"},
+ {"BM", "bmp"},
+ {"\x89PNG\x0d\x0a\x1a\x0a", "png"},
+ {"P1", "pnm"},
+ {"P2", "pnm"},
+ {"P3", "pnm"},
+ {"P4", "pnm"},
+ {"P5", "pnm"},
+ {"P6", "pnm"},
+ };
+ unsigned int i;
+ char head[18];
+ char *match = NULL;
+ ssize_t rc;
+
+ io_glue_commit_types(data);
+ rc = data->readcb(data, head, 18);
+ if (rc == -1) return NULL;
+ data->seekcb(data, -rc, SEEK_CUR);
+
+ for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
+ int c;
+ ssize_t len = strlen(formats[i].magic);
+ if (rc<len) continue;
+ c = !strncmp(formats[i].magic, head, len);
+ if (c) {
+ match = formats[i].name;
+ break;
+ }
+ }
+
+ /*
+ if (match && !strcmp(match, "jpeg")) {
+ unsigned int x0, x1;
+ rc = data->readcb(data, head, 18);
+ if (rc == -1) return NULL;
+ x0 = (unsigned char)head[0];
+ x1 = (unsigned char)head[1];
+ data->seekcb(data, -rc, SEEK_CUR);
+ printf("Jpeg reread: %x %x\n", x0, x1);
+ }
+ */
+
+ if (!match &&
+ (rc == 18) &&
+ tga_header_verify(head)) return "tga";
+ return match;
+}
+
+
+
+
/*
=back