+static void free_images(i_img **imgs, int count) {
+ int i;
+
+ if (count) {
+ for (i = 0; i < count; ++i)
+ i_img_destroy(imgs[i]);
+ myfree(imgs);
+ }
+}
+
+i_img **i_readpnm_multi_wiol(io_glue *ig, int *count, int allow_incomplete) {
+ i_img **results = NULL;
+ i_img *img = NULL;
+ char c = EOF;
+ int result_alloc = 0,
+ value = 0,
+ eof = 0;
+ *count=0;
+
+ do {
+ mm_log((1, "read image %i\n", 1+*count));
+ img = i_readpnm_wiol( ig, allow_incomplete );
+ if( !img ) {
+ free_images( results, *count );
+ return NULL;
+ }
+ ++*count;
+ if (*count > result_alloc) {
+ if (result_alloc == 0) {
+ result_alloc = 5;
+ results = mymalloc(result_alloc * sizeof(i_img *));
+ }
+ else {
+ /* myrealloc never fails (it just dies if it can't allocate) */
+ result_alloc *= 2;
+ results = myrealloc(results, result_alloc * sizeof(i_img *));
+ }
+ }
+ results[*count-1] = img;
+
+
+ if( i_tags_get_int(&img->tags, "i_incomplete", 0, &value ) && value) {
+ eof = 1;
+ }
+ else if( skip_spaces( ig ) && ( c=i_io_peekc( ig ) ) != EOF && c == 'P' ) {
+ eof = 0;
+ }
+ else {
+ eof = 1;
+ }
+ } while(!eof);
+ return results;
+}
+
+
+
+static
+int
+write_pbm(i_img *im, io_glue *ig, int zero_is_white) {
+ int x, y;
+ i_palidx *line;
+ i_img_dim write_size;
+ unsigned char *write_buf;
+ unsigned char *writep;
+ char header[255];
+ unsigned mask;
+
+ 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;
+ }
+ write_size = (im->xsize + 7) / 8;
+ line = mymalloc(sizeof(i_palidx) * im->xsize);
+ write_buf = mymalloc(write_size);
+ for (y = 0; y < im->ysize; ++y) {
+ i_gpal(im, 0, im->xsize, y, line);
+ mask = 0x80;
+ writep = write_buf;
+ memset(write_buf, 0, write_size);
+ for (x = 0; x < im->xsize; ++x) {
+ if (zero_is_white ? line[x] : !line[x])
+ *writep |= mask;
+ mask >>= 1;
+ if (!mask) {
+ ++writep;
+ mask = 0x80;
+ }
+ }
+ if (i_io_write(ig, write_buf, write_size) != write_size) {
+ i_push_error(0, "write failure");
+ myfree(write_buf);
+ myfree(line);
+ return 0;
+ }
+ }
+ myfree(write_buf);
+ myfree(line);
+
+ return 1;
+}
+
+static
+int
+write_ppm_data_8(i_img *im, io_glue *ig, int want_channels) {
+ size_t write_size = im->xsize * want_channels;
+ size_t buf_size = im->xsize * im->channels;
+ unsigned char *data = mymalloc(buf_size);
+ i_img_dim y = 0;
+ int rc = 1;
+ i_color bg;
+
+ i_get_file_background(im, &bg);
+ while (y < im->ysize && rc >= 0) {
+ i_gsamp_bg(im, 0, im->xsize, y, data, want_channels, &bg);
+ if (i_io_write(ig, data, write_size) != write_size) {
+ i_push_error(errno, "could not write ppm data");
+ rc = 0;
+ break;
+ }
+ ++y;
+ }
+ myfree(data);
+
+ return rc;
+}
+
+static
+int
+write_ppm_data_16(i_img *im, io_glue *ig, int want_channels) {
+ 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;
+ size_t sample_num;
+ i_img_dim y = 0;
+ int rc = 1;
+ i_fcolor bg;
+
+ i_get_file_backgroundf(im, &bg);
+
+ while (y < im->ysize) {
+ i_gsampf_bg(im, 0, im->xsize, y, line_buf, want_channels, &bg);
+ samplep = line_buf;
+ writep = write_buf;
+ for (sample_num = 0; sample_num < sample_count; ++sample_num) {
+ unsigned sample16 = SampleFTo16(*samplep++);
+ *writep++ = sample16 >> 8;
+ *writep++ = sample16 & 0xFF;
+ }
+ if (i_io_write(ig, write_buf, write_size) != write_size) {
+ i_push_error(errno, "could not write ppm data");
+ rc = 0;
+ break;
+ }
+ ++y;
+ }
+ myfree(line_buf);
+ myfree(write_buf);
+
+ return rc;
+}