+static
+i_img *
+read_pgm_ppm_bin8(io_glue *ig, i_img *im, int width, int height,
+ int channels, int maxval, int allow_incomplete) {
+ i_color *line, *linep;
+ int read_size;
+ unsigned char *read_buf, *readp;
+ int x, y, ch;
+ int rounder = maxval / 2;
+
+ line = mymalloc(width * sizeof(i_color));
+ read_size = channels * width;
+ read_buf = mymalloc(read_size);
+ for(y=0;y<height;y++) {
+ linep = line;
+ readp = read_buf;
+ if (i_io_read(ig, read_buf, read_size) != read_size) {
+ myfree(line);
+ myfree(read_buf);
+ if (allow_incomplete) {
+ i_tags_setn(&im->tags, "i_incomplete", 1);
+ i_tags_setn(&im->tags, "i_lines_read", y);
+ return im;
+ }
+ else {
+ i_push_error(0, "short read - file truncated?");
+ i_img_destroy(im);
+ return NULL;
+ }
+ }
+ if (maxval == 255) {
+ for(x=0; x<width; x++) {
+ for(ch=0; ch<channels; ch++) {
+ linep->channel[ch] = *readp++;
+ }
+ ++linep;
+ }
+ }
+ else {
+ for(x=0; x<width; x++) {
+ for(ch=0; ch<channels; ch++) {
+ /* we just clamp samples to the correct range */
+ unsigned sample = *readp++;
+ if (sample > maxval)
+ sample = maxval;
+ linep->channel[ch] = (sample * 255 + rounder) / maxval;
+ }
+ ++linep;
+ }
+ }
+ i_plin(im, 0, width, y, line);
+ }
+ myfree(read_buf);
+ myfree(line);
+
+ return im;
+}
+
+static
+i_img *
+read_pgm_ppm_bin16(io_glue *ig, i_img *im, int width, int height,
+ int channels, int maxval, int allow_incomplete) {
+ i_fcolor *line, *linep;
+ int read_size;
+ unsigned char *read_buf, *readp;
+ int x, y, ch;
+ double maxvalf = maxval;
+
+ line = mymalloc(width * sizeof(i_fcolor));
+ read_size = channels * width * 2;
+ read_buf = mymalloc(read_size);
+ for(y=0;y<height;y++) {
+ linep = line;
+ readp = read_buf;
+ if (i_io_read(ig, read_buf, read_size) != read_size) {
+ myfree(line);
+ myfree(read_buf);
+ if (allow_incomplete) {
+ i_tags_setn(&im->tags, "i_incomplete", 1);
+ i_tags_setn(&im->tags, "i_lines_read", y);
+ return im;
+ }
+ else {
+ i_push_error(0, "short read - file truncated?");
+ i_img_destroy(im);
+ return NULL;
+ }
+ }
+ for(x=0; x<width; x++) {
+ for(ch=0; ch<channels; ch++) {
+ unsigned sample = (readp[0] << 8) + readp[1];
+ if (sample > maxval)
+ sample = maxval;
+ readp += 2;
+ linep->channel[ch] = sample / maxvalf;
+ }
+ ++linep;
+ }
+ i_plinf(im, 0, width, y, line);
+ }
+ myfree(read_buf);
+ myfree(line);