X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/faa9b3e727c7c57aa07598dc0ba2ada24eb3f9a8..64ddd21f418352d0b77df9963cf7f7a0577d7c47:/pnm.c diff --git a/pnm.c b/pnm.c index 2765c4c7..e5d30504 100644 --- a/pnm.c +++ b/pnm.c @@ -1,7 +1,7 @@ -#include "image.h" -#include "io.h" +#include "imager.h" #include "log.h" #include "iolayer.h" +#include "imageri.h" #include #include @@ -30,7 +30,7 @@ or an entire memory mapped buffer. Some of these functions are internal. -=over 4 +=over =cut */ @@ -98,7 +98,7 @@ gnext(mbuf *mb) { /* -=item gnext(mbuf *mb) +=item gpeek(mbuf *mb) Fetches a character but does NOT advance. Returns a pointer to the byte or NULL on failure (internal). @@ -154,7 +154,7 @@ skip_spaces(mbuf *mb) { /* -=item skip_spaces(mb) +=item skip_comment(mb) Advances in stream over whitespace and a comment if one is found. (internal) @@ -229,32 +229,16 @@ i_readpnm_wiol(io_glue *ig, int length) { int type; int x, y, ch; int width, height, maxval, channels, pcount; + int rounder; char *cp; unsigned char *uc; mbuf buf; i_color val; - int mult; i_clear_error(); - /* char *pp; */ - mm_log((1,"i_readpnm(ig %p, length %d)\n", ig, length)); - /* - pp = mymalloc(20); - - pp[-1]= 'c'; - pp[-2]= 'c'; - - bndcheck_all(); - - myfree(pp); - - mm_log((1, "Hack is exiting\n")); - -*/ - io_glue_commit_types(ig); init_buf(&buf, ig); @@ -331,7 +315,25 @@ i_readpnm_wiol(io_glue *ig, int length) { mm_log((1, "i_readpnm: error reading maxval\n")); return NULL; } + + if (maxval == 0) { + i_push_error(0, "maxval is zero - invalid pnm file"); + mm_log((1, "i_readpnm: maxval is zero, invalid pnm file\n")); + return NULL; + } + 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")); + return NULL; + } + else if (type >= 4 && maxval > 255) { + i_push_errorf(0, "maxval of %d is over 255 - not currently supported by Imager for binary pnm", maxval); + mm_log((1, "i_readpnm: maxval of %d is over 255 - not currently supported by Imager for binary pnm\n", maxval)); + return NULL; + } } else maxval=1; + rounder = maxval / 2; if (!(cp = gnext(&buf)) || !misspace(*cp)) { i_push_error(0, "garbage in header, invalid PNM file"); @@ -342,19 +344,25 @@ i_readpnm_wiol(io_glue *ig, int length) { 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")); + return NULL; + } + mm_log((1, "i_readpnm: (%d x %d), channels = %d, maxval = %d\n", width, height, channels, maxval)); im = i_img_empty_ch(NULL, width, height, channels); + i_tags_add(&im->tags, "i_format", 0, "pnm", -1, 0); + switch (type) { case 1: /* Ascii types */ case 2: case 3: - mult = type == 1 ? 255 : 1; for(y=0;ychannels==3) { - sprintf(header,"P6\n#CREATOR: Imager\n%d %d\n255\n",im->xsize,im->ysize); - - if (mywrite(fd,header,strlen(header))<0) { - i_push_error(errno, "could not write ppm header"); - mm_log((1,"i_writeppm: unable to write ppm header.\n")); - return(0); - } - - if (!im->virtual && im->bits == i_8_bits && im->type == i_direct_type) { - rc=mywrite(fd,im->idata,im->bytes); - } - else { - unsigned char *data = mymalloc(3 * im->xsize); - if (data != NULL) { - int y = 0; - int x, ch; - unsigned char *p; - static int rgb_chan[3] = { 0, 1, 2 }; - - rc = 0; - while (y < im->ysize && rc >= 0) { - i_gsamp(im, 0, im->xsize, y, data, rgb_chan, 3); - rc = mywrite(fd, data, im->xsize * 3); - } - myfree(data); - } - else { - i_push_error(0, "Out of memory"); - return 0; - } - } - if (rc<0) { - i_push_error(errno, "could not write ppm data"); - mm_log((1,"i_writeppm: unable to write ppm data.\n")); - return(0); - } - } - else if (im->channels == 1) { - sprintf(header, "P5\n#CREATOR: Imager\n%d %d\n255\n", - im->xsize, im->ysize); - if (mywrite(fd,header, strlen(header)) < 0) { - i_push_error(errno, "could not write pgm header"); - mm_log((1,"i_writeppm: unable to write pgm header.\n")); - return(0); - } - - if (!im->virtual && im->bits == i_8_bits && im->type == i_direct_type) { - rc=mywrite(fd,im->idata,im->bytes); - } - else { - unsigned char *data = mymalloc(im->xsize); - if (data != NULL) { - int y = 0; - int x, ch; - int chan = 0; - unsigned char *p; - - rc = 0; - while (y < im->ysize && rc >= 0) { - i_gsamp(im, 0, im->xsize, y, data, &chan, 1); - rc = mywrite(fd, data, im->xsize); - } - myfree(data); - } - else { - i_push_error(0, "Out of memory"); - return 0; - } - } - if (rc<0) { - i_push_error(errno, "could not write pgm data"); - mm_log((1,"i_writeppm: unable to write pgm data.\n")); - return(0); - } - } - else { - i_push_error(0, "can only save 1 or 3 channel images to pnm"); - mm_log((1,"i_writeppm: ppm/pgm is 1 or 3 channel only (current image is %d)\n",im->channels)); - return(0); - } - - return(1); -} - undef_int i_writeppm_wiol(i_img *im, io_glue *ig) { char header[255]; int rc; - writep write_func; mm_log((1,"i_writeppm(im %p, ig %p)\n", im, ig)); i_clear_error(); @@ -525,14 +439,13 @@ i_writeppm_wiol(i_img *im, io_glue *ig) { unsigned char *data = mymalloc(3 * im->xsize); if (data != NULL) { int y = 0; - int x, ch; - unsigned char *p; static int rgb_chan[3] = { 0, 1, 2 }; rc = 0; while (y < im->ysize && rc >= 0) { i_gsamp(im, 0, im->xsize, y, data, rgb_chan, 3); rc = ig->writecb(ig, data, im->xsize * 3); + ++y; } myfree(data); } @@ -563,14 +476,13 @@ i_writeppm_wiol(i_img *im, io_glue *ig) { unsigned char *data = mymalloc(im->xsize); if (data != NULL) { int y = 0; - int x, ch; int chan = 0; - unsigned char *p; rc = 0; while (y < im->ysize && rc >= 0) { i_gsamp(im, 0, im->xsize, y, data, &chan, 1); rc = ig->writecb(ig, data, im->xsize); + ++y; } myfree(data); } @@ -590,6 +502,21 @@ i_writeppm_wiol(i_img *im, io_glue *ig) { mm_log((1,"i_writeppm: ppm/pgm is 1 or 3 channel only (current image is %d)\n",im->channels)); return(0); } + ig->closecb(ig); return(1); } + +/* +=back + +=head1 AUTHOR + +Arnar M. Hrafnkelsson + +=head1 SEE ALSO + +Imager(3) + +=cut +*/