get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) /* This version is for reading text-format PPM files with any maxval */ { ppm_source_ptr source = (ppm_source_ptr) sinfo; FILE * infile = source->pub.input_file; register JSAMPROW ptr; register JSAMPLE *rescale = source->rescale; JDIMENSION col; ptr = source->pub.buffer[0]; for (col = cinfo->image_width; col > 0; col--) { *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; } return 1; }
LOCAL void read_ppm_map (j_decompress_ptr cinfo, FILE * infile) { int c; unsigned int w, h, maxval, row, col; int R, G, B; /* Initial 'P' has already been read by read_color_map */ c = getc(infile); /* save format discriminator for a sec */ /* while we fetch the remaining header info */ w = read_pbm_integer(cinfo, infile); h = read_pbm_integer(cinfo, infile); maxval = read_pbm_integer(cinfo, infile); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_BAD_CMAP_FILE); /* For now, we don't support rescaling from an unusual maxval. */ if (maxval != (unsigned int) MAXJSAMPLE) ERREXIT(cinfo, JERR_BAD_CMAP_FILE); switch (c) { case '3': /* it's a text-format PPM file */ for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { R = read_pbm_integer(cinfo, infile); G = read_pbm_integer(cinfo, infile); B = read_pbm_integer(cinfo, infile); add_map_entry(cinfo, R, G, B); } } break; case '6': /* it's a raw-format PPM file */ for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { R = pbm_getc(infile); G = pbm_getc(infile); B = pbm_getc(infile); if (R == EOF || G == EOF || B == EOF) ERREXIT(cinfo, JERR_BAD_CMAP_FILE); add_map_entry(cinfo, R, G, B); } } break; default: ERREXIT(cinfo, JERR_BAD_CMAP_FILE); break; } }
start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { ppm_source_ptr source = (ppm_source_ptr) sinfo; int c; unsigned int w, h, maxval; boolean need_iobuffer, use_raw_buffer, need_rescale; if (getc(source->pub.input_file) != 'P') ERREXIT(cinfo, JERR_PPM_NOT); c = getc(source->pub.input_file); /* subformat discriminator character */ /* detect unsupported variants (ie, PBM) before trying to read header */ switch (c) { case '2': /* it's a text-format PGM file */ case '3': /* it's a text-format PPM file */ case '5': /* it's a raw-format PGM file */ case '6': /* it's a raw-format PPM file */ break; default: ERREXIT(cinfo, JERR_PPM_NOT); break; } /* fetch the remaining header info */ w = read_pbm_integer(cinfo, source->pub.input_file, 65535); h = read_pbm_integer(cinfo, source->pub.input_file, 65535); maxval = read_pbm_integer(cinfo, source->pub.input_file, 65535); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ cinfo->image_width = (JDIMENSION) w; cinfo->image_height = (JDIMENSION) h; source->maxval = maxval; /* initialize flags to most common settings */ need_iobuffer = TRUE; /* do we need an I/O buffer? */ use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ need_rescale = TRUE; /* do we need a rescale array? */ switch (c) { case '2': /* it's a text-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); source->pub.get_pixel_rows = get_text_gray_row; need_iobuffer = FALSE; break; case '3': /* it's a text-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); source->pub.get_pixel_rows = get_text_rgb_row; need_iobuffer = FALSE; break; case '5': /* it's a raw-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM, w, h); if (maxval > 255) { source->pub.get_pixel_rows = get_word_gray_row; } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; need_rescale = FALSE; } else { source->pub.get_pixel_rows = get_scaled_gray_row; } break; case '6': /* it's a raw-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM, w, h); if (maxval > 255) { source->pub.get_pixel_rows = get_word_rgb_row; } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; need_rescale = FALSE; } else { source->pub.get_pixel_rows = get_scaled_rgb_row; } break; } /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ if (need_iobuffer) { source->buffer_width = (size_t) w * cinfo->input_components * ((maxval<=255) ? sizeof(U_CHAR) : (2*sizeof(U_CHAR))); source->iobuffer = (U_CHAR *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, source->buffer_width); } /* Create compressor input buffer. */ if (use_raw_buffer) { /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ /* Synthesize a JSAMPARRAY pointer structure */ source->pixrow = (JSAMPROW) source->iobuffer; source->pub.buffer = & source->pixrow; source->pub.buffer_height = 1; } else { /* Need to translate anyway, so make a separate sample buffer. */ source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); source->pub.buffer_height = 1; } /* Compute the rescaling array if required. */ if (need_rescale) { INT32 val, half_maxval; /* On 16-bit-int machines we have to be careful of maxval = 65535 */ source->rescale = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * sizeof(JSAMPLE))); half_maxval = maxval / 2; for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); } } }
rows rdppm (info *pinf, FILE *in) //deve ritornare rdppm puntatore righe e info mediante puntatore { FILE *source = in; int file,real_columns,real_rows,horiz_border,vertical_border,i,j,z,scale; rows p_icture; unsigned char value[3]; unsigned char ch; fread(&ch,1,1,source); if (ch != 'P') { printf("Input file is not a portable pixel/grey map \n"); return NULL; } fread(&ch,1,1,source); file = ch -'0'; if ((file<2)||(file>6)||(file==4)) { printf("PBM is not supported\n"); return NULL; } real_columns = read_pbm_integer(source); real_rows = read_pbm_integer(source); pinf->maxsample = read_pbm_integer(source); if (real_columns <= 0 || real_rows <= 0 || pinf->maxsample <= 0) { printf("Reading error\n"); return NULL; } horiz_border=8-real_columns%8; if (horiz_border>7) horiz_border=0; pinf->L=real_columns+horiz_border; vertical_border=8-real_rows%8; if (vertical_border>7) vertical_border=0; pinf->H=real_rows+vertical_border; pinf->numrows=pinf->H/8; pinf->numblocks=pinf->L/8; if ((file==3)||(file==6)) pinf->color=1; else pinf->color=0; scale=255/pinf->maxsample; pinf->maxsample=255; p_icture=(p_block *) malloc (pinf->numrows*sizeof(p_block)); for (i=0;i<pinf->numrows;i++) *(p_icture+i)=(block *) malloc (pinf->numblocks*sizeof(block)); switch (file) { case 2: //grayscale ascii { for (i=0;i<pinf->H;i++) for (j=0;j<pinf->L;j++) { int position=(i%8)*8+j%8; if (i>=real_rows) { int last_position=((real_rows-1)%8)*8+j%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; } else if (j>=real_columns) { int last_position=(i%8)*8+(real_columns-1)%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; } else value[0]=read_pbm_integer(source)*scale; (*(p_icture+i/8)+j/8)->comp1[position]=value[0]; (*(p_icture+i/8)+j/8)->comp2[position]=0; (*(p_icture+i/8)+j/8)->comp3[position]=0; } } break; case 3: //color ascii { for (i=0;i<pinf->H;i++) for (j=0;j<pinf->L;j++) { int position=(i%8)*8+j%8; if (i>=real_rows) { int last_position=((real_rows-1)%8)*8+j%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; value[1]=(*(p_icture+i/8)+j/8)->comp2[last_position]; value[2]=(*(p_icture+i/8)+j/8)->comp3[last_position]; } else if (j>=real_columns) { int last_position=(i%8)*8+(real_columns-1)%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; value[1]=(*(p_icture+i/8)+j/8)->comp2[last_position]; value[2]=(*(p_icture+i/8)+j/8)->comp3[last_position]; } else for (z=0;z<3;z++) value[z]=read_pbm_integer(source)*scale; (*(p_icture+i/8)+j/8)->comp1[position]=value[0]; (*(p_icture+i/8)+j/8)->comp2[position]=value[1]; (*(p_icture+i/8)+j/8)->comp3[position]=value[2]; } } break; case 5: //grayscale rawbit { for (i=0;i<pinf->H;i++) for (j=0;j<pinf->L;j++) { int position=(i%8)*8+j%8; if (i>=real_rows) { int last_position=((real_rows-1)%8)*8+j%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; } else if (j>=real_columns) { int last_position=(i%8)*8+(real_columns-1)%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; } else { fread(&value[0],sizeof(char),1,source); value[0]*=scale; } (*(p_icture+i/8)+j/8)->comp1[position]=value[0]; (*(p_icture+i/8)+j/8)->comp2[position]=0; (*(p_icture+i/8)+j/8)->comp3[position]=0; } } break; case 6: //color rawbit { for (i=0;i<pinf->H;i++) { for (j=0;j<pinf->L;j++) { int position=(i%8)*8+j%8; if (i>=real_rows) { int last_position=((real_rows-1)%8)*8+j%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; value[1]=(*(p_icture+i/8)+j/8)->comp2[last_position]; value[2]=(*(p_icture+i/8)+j/8)->comp3[last_position]; } else if (j>=real_columns) { int last_position=(i%8)*8+(real_columns-1)%8; value[0]=(*(p_icture+i/8)+j/8)->comp1[last_position]; value[1]=(*(p_icture+i/8)+j/8)->comp2[last_position]; value[2]=(*(p_icture+i/8)+j/8)->comp3[last_position]; } else { fread(&value[0],sizeof(char),1,source); fread(&value[1],sizeof(char),1,source); fread(&value[2],sizeof(char),1,source); value[0]*=scale; value[1]*=scale; value[2]*=scale; } (*(p_icture+i/8)+j/8)->comp1[position]=value[0]; (*(p_icture+i/8)+j/8)->comp2[position]=value[1]; (*(p_icture+i/8)+j/8)->comp3[position]=value[2]; } } } break; } pinf->H=real_rows; pinf->L=real_columns; return(p_icture); }
read_ppm_map (j_decompress_ptr cinfo, FILE * infile) { int c; __boundcheck_metadata_store((void *)(&c),(void *)((size_t)(&c)+sizeof(c)*8-1)); unsigned int w; __boundcheck_metadata_store((void *)(&w),(void *)((size_t)(&w)+sizeof(w)*8-1)); unsigned int h; __boundcheck_metadata_store((void *)(&h),(void *)((size_t)(&h)+sizeof(h)*8-1)); unsigned int maxval; __boundcheck_metadata_store((void *)(&maxval),(void *)((size_t)(&maxval)+sizeof(maxval)*8-1)); unsigned int row; __boundcheck_metadata_store((void *)(&row),(void *)((size_t)(&row)+sizeof(row)*8-1)); unsigned int col; __boundcheck_metadata_store((void *)(&col),(void *)((size_t)(&col)+sizeof(col)*8-1)); int R; __boundcheck_metadata_store((void *)(&R),(void *)((size_t)(&R)+sizeof(R)*8-1)); int G; __boundcheck_metadata_store((void *)(&G),(void *)((size_t)(&G)+sizeof(G)*8-1)); int B; __boundcheck_metadata_store((void *)(&B),(void *)((size_t)(&B)+sizeof(B)*8-1)); /* Initial 'P' has already been read by read_color_map */ c = getc(infile); /* save format discriminator for a sec */ /* while we fetch the remaining header info */ w = read_pbm_integer(cinfo, infile); h = read_pbm_integer(cinfo, infile); maxval = read_pbm_integer(cinfo, infile); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_BAD_CMAP_FILE); /* For now, we don't support rescaling from an unusual maxval. */ if (maxval != (unsigned int) MAXJSAMPLE) ERREXIT(cinfo, JERR_BAD_CMAP_FILE); switch (c) { case '3': /* it's a text-format PPM file */ for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { R = read_pbm_integer(cinfo, infile); G = read_pbm_integer(cinfo, infile); B = read_pbm_integer(cinfo, infile); add_map_entry(cinfo, R, G, B); } } break; case '6': /* it's a raw-format PPM file */ for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { R = pbm_getc(infile); G = pbm_getc(infile); B = pbm_getc(infile); if (R == EOF || G == EOF || B == EOF) ERREXIT(cinfo, JERR_BAD_CMAP_FILE); add_map_entry(cinfo, R, G, B); } } break; default: ERREXIT(cinfo, JERR_BAD_CMAP_FILE); break; } }
start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { ppm_source_ptr source = (ppm_source_ptr) sinfo; int c, bit_width; unsigned int w, h, maxval; /* On 16-bit-int machines we have to be careful of maxval = 65535 + 1 */ long maxval_shift; boolean need_iobuffer, use_raw_buffer, need_rescale; if (getc(source->pub.input_file) != 'P') ERREXIT(cinfo, JERR_PPM_NOT); c = getc(source->pub.input_file); /* subformat discriminator character */ /* detect unsupported variants (ie, PBM) before trying to read header */ switch (c) { case '2': /* it's a text-format PGM file */ case '3': /* it's a text-format PPM file */ case '5': /* it's a raw-format PGM file */ case '6': /* it's a raw-format PPM file */ break; default: ERREXIT(cinfo, JERR_PPM_NOT); break; } /* fetch the remaining header info */ w = read_pbm_integer(cinfo, source->pub.input_file); h = read_pbm_integer(cinfo, source->pub.input_file); maxval = read_pbm_integer(cinfo, source->pub.input_file); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); /* cinfo->data_precision = BITS_IN_JSAMPLE;*/ /* we always rescale data to this */ /* Find the # of bits for maxval. */ cinfo->data_precision_other = 0; for (maxval_shift = (long)maxval + 1L ; maxval_shift > 1; maxval_shift >>= 1) cinfo->data_precision_other++; /* Set to 0 for: use input value from file */ if (cinfo->data_precision == 0) cinfo->data_precision = cinfo->data_precision_other; cinfo->image_width = (JDIMENSION) w; cinfo->image_height = (JDIMENSION) h; /* initialize flags to most common settings */ need_iobuffer = TRUE; /* do we need an I/O buffer? */ use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ need_rescale = TRUE; /* do we need a rescale array? */ switch (c) { case '2': /* it's a text-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); if (cinfo->data_precision <= 8) source->pub.get_pixel_rows = get_text_gray_row; else source->pub.get_pixel_rows = get_text_gray_row16; need_iobuffer = FALSE; break; case '3': /* it's a text-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); if (cinfo->data_precision <= 8) source->pub.get_pixel_rows = get_text_rgb_row; else source->pub.get_pixel_rows = get_text_rgb_row16; need_iobuffer = FALSE; break; case '5': /* it's a raw-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM, w, h); if (cinfo->data_precision == cinfo->data_precision_other) { need_rescale = FALSE; if (cinfo->data_precision > 8) { source->pub.get_pixel_rows = get_corr_row16; use_raw_buffer = FALSE; } else { /* 8 bit*/ source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; } } else if (cinfo->data_precision > 8) { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_word_gray_row16; else source->pub.get_pixel_rows = get_word_gray_row; } else { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_scaled_gray_row16; else source->pub.get_pixel_rows = get_scaled_gray_row; } break; case '6': /* it's a raw-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM, w, h); if (cinfo->data_precision == cinfo->data_precision_other) { need_rescale = FALSE; if (cinfo->data_precision > 8) { source->pub.get_pixel_rows = get_corr_row16; use_raw_buffer = FALSE; } else { /* 8 bit*/ source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; } } else if (cinfo->data_precision > 8) { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_word_rgb_row16; else source->pub.get_pixel_rows = get_word_rgb_row; } else { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_scaled_rgb_row16; else source->pub.get_pixel_rows = get_scaled_rgb_row; } break; } /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ if (need_iobuffer) { source->buffer_width = (size_t) w * cinfo->input_components * ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR))); source->iobuffer = (U_CHAR *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, source->buffer_width); } /* Create compressor input buffer. */ bit_width = ((cinfo->data_precision<=8) ? SIZEOF(JSAMPLE) : SIZEOF(JSAMPLE16)); if (use_raw_buffer) { /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ /* Synthesize a JSAMPARRAY pointer structure */ /* Cast here implies near->far pointer conversion on PCs */ source->pixrow = (JSAMPROW) source->iobuffer; source->pub.buffer = & source->pixrow; source->pub.buffer_height = 1; } else { /* Need to translate anyway, so make a separate sample buffer. */ source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) w * cinfo->input_components * bit_width, (JDIMENSION) 1); source->pub.buffer_height = 1; } /* Compute the rescaling array if required. */ cinfo->lossless_scaling = FALSE; if (need_rescale) { INT32 val, half_maxval, maxjsample; /* On 16-bit-int machines we have to be careful of maxval = 65535 */ source->rescale = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * (long)bit_width)); half_maxval = maxval / 2; maxjsample = (1 << cinfo->data_precision) - 1; if (bit_width == 1) { if (maxjsample == maxval) { for (val = 0; val <= (INT32) maxval; val++) source->rescale[val] = val; } else { for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ source->rescale[val] = (JSAMPLE) ((val*maxjsample + half_maxval)/maxval); } } } else { JSAMPLE16 *rescale16; rescale16 = (JSAMPLE16 *)source->rescale; if (maxjsample == maxval) { for (val = 0; val <= (INT32) maxval; val++) rescale16[val] = val; } else { for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ rescale16[val] = (JSAMPLE16) ((val*maxjsample + half_maxval)/maxval); } } } } }