📄 image_out.cpp
字号:
else { kdu_error e; e << "Cannot use 16-bit representation with high " "bit-depth data"; }}/*****************************************************************************//* STATIC convert_ints_to_words *//*****************************************************************************/static void convert_ints_to_words(kdu_sample32 *src, kdu_byte *dest, int num, int precision, bool is_signed, int sample_bytes){ kdu_int32 val, min, max, offset; offset = 1<<(precision-1); min = -offset; max = (1<<precision)-1-offset; offset = (is_signed)?0:offset; if (sample_bytes == 1) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte) val; } else if (sample_bytes == 2) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else if (sample_bytes == 3) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte)(val>>16); *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else if (sample_bytes == 4) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte)(val>>24); *(dest++) = (kdu_byte)(val>>16); *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else assert(0);}/*****************************************************************************//* STATIC convert_shorts_to_words *//*****************************************************************************/static void convert_shorts_to_words(kdu_sample16 *src, kdu_byte *dest, int num, int precision, bool is_signed, int sample_bytes){ kdu_int32 val, min, max, offset; offset = 1<<(precision-1); min = -offset; max = (1<<precision)-1-offset; offset = (is_signed)?0:offset; if (sample_bytes == 1) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte) val; } else if (sample_bytes == 2) for (; num > 0; num--, src++) { val = src->ival; val = (val>min)?val:min; val = (val<max)?val:max; val += offset; *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else { kdu_error e; e << "Cannot use 16-bit representation with high " "bit-depth data"; }}/* ========================================================================= *//* kdu_image_out *//* ========================================================================= *//*****************************************************************************//* kdu_image_out::kdu_image_out *//*****************************************************************************/kdu_image_out::kdu_image_out(char const *fname, kdu_image_dims &dims, int &next_comp_idx, bool &vflip){ char const *suffix; out = NULL; vflip = false; if ((suffix = strrchr(fname,'.')) != NULL) { if ((strcmp(suffix+1,"pgm") == 0) || (strcmp(suffix+1,"PGM") == 0)) out = new pgm_out(fname,dims,next_comp_idx); else if ((strcmp(suffix+1,"ppm") == 0) || (strcmp(suffix+1,"PPM") == 0)) out = new ppm_out(fname,dims,next_comp_idx); else if ((strcmp(suffix+1,"bmp") == 0) || (strcmp(suffix+1,"BMP") == 0)) { vflip = true; out = new bmp_out(fname,dims,next_comp_idx); } else if ((strcmp(suffix+1,"raw") == 0) || (strcmp(suffix+1,"RAW") == 0)) out = new raw_out(fname,dims,next_comp_idx); } if (out == NULL) { kdu_error e; e << "Image file, \"" << fname << ", does not have a " "recognized suffix. Valid suffices are currently: " "\"bmp\", \"pgm\", \"ppm\" and \"raw\". " "Upper or lower case may be used, but must be used consistently."; }}/* ========================================================================= *//* pgm_out *//* ========================================================================= *//*****************************************************************************//* pgm_out::pgm_out *//*****************************************************************************/pgm_out::pgm_out(char const *fname, kdu_image_dims &dims, int &next_comp_idx){ int is_signed; comp_idx = next_comp_idx++; if (comp_idx >= dims.get_num_components()) { kdu_error e; e << "Output image files require more image components " "(or mapped colour channels) than are available!"; } rows = dims.get_height(comp_idx); cols = dims.get_width(comp_idx); precision = dims.get_bit_depth(comp_idx); is_signed = dims.get_signed(comp_idx); if (is_signed) { kdu_warning w; w << "Signed sample values will be written to the PGM file as unsigned " "8-bit quantities, centered about 128."; } if ((out = fopen(fname,"wb")) == NULL) { kdu_error e; e << "Unable to open output image file, \"" << fname <<"\"."; } fprintf(out,"P5\n%d %d\n255\n",cols,rows); incomplete_lines = free_lines = NULL; num_unwritten_rows = rows;}/*****************************************************************************//* pgm_out::~pgm_out *//*****************************************************************************/pgm_out::~pgm_out(){ if ((num_unwritten_rows > 0) || (incomplete_lines != NULL)) { kdu_warning w; w << "Not all rows of image component " << comp_idx << " were completed!"; } image_line_buf *tmp; while ((tmp=incomplete_lines) != NULL) { incomplete_lines = tmp->next; delete tmp; } while ((tmp=free_lines) != NULL) { free_lines = tmp->next; delete tmp; } fclose(out);}/*****************************************************************************//* pgm_out::put *//*****************************************************************************/void pgm_out::put(int comp_idx, kdu_line_buf &line, int x_tnum){ assert(comp_idx == this->comp_idx); image_line_buf *scan, *prev=NULL; for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next) { assert(scan->next_x_tnum >= x_tnum); if (scan->next_x_tnum == x_tnum) break; } if (scan == NULL) { // Need to open a new line buffer. assert(x_tnum == 0); // Must supply samples from left to right. if ((scan = free_lines) == NULL) scan = new image_line_buf(cols,1); free_lines = scan->next; if (prev == NULL) incomplete_lines = scan; else prev->next = scan; scan->accessed_samples = 0; scan->next_x_tnum = 0; } assert((scan->width-scan->accessed_samples) >= line.get_width()); if (line.get_buf32() != NULL) { if (line.is_absolute()) convert_ints_to_bytes(line.get_buf32(), scan->buf+scan->accessed_samples, line.get_width(),precision); else convert_floats_to_bytes(line.get_buf32(), scan->buf+scan->accessed_samples, line.get_width(),precision); } else { if (line.is_absolute()) convert_shorts_to_bytes(line.get_buf16(), scan->buf+scan->accessed_samples, line.get_width(),precision); else convert_fixpoint_to_bytes(line.get_buf16(), scan->buf+scan->accessed_samples, line.get_width(),precision); } scan->next_x_tnum++; scan->accessed_samples += line.get_width(); if (scan->accessed_samples == scan->width) { // Write completed line and send it to the free list. if (num_unwritten_rows == 0) { kdu_error e; e << "Attempting to write too many lines to image " "file for component " << comp_idx << "."; } if (fwrite(scan->buf,1,(size_t) scan->width,out) != (size_t) scan->width) { kdu_error e; e << "Unable to write to image file for component " << comp_idx << ". File may be write protected, or disk may be full."; } num_unwritten_rows--; assert(scan == incomplete_lines); incomplete_lines = scan->next; scan->next = free_lines; free_lines = scan; }}/* ========================================================================= *//* ppm_out *//* ========================================================================= *//*****************************************************************************//* ppm_out::ppm_out *//*****************************************************************************/ppm_out::ppm_out(char const *fname, kdu_image_dims &dims, int &next_comp_idx){ bool is_signed; int n; first_comp_idx = next_comp_idx; if ((first_comp_idx+2) >= dims.get_num_components()) { kdu_error e; e << "Output image files require more image components " "(or mapped colour channels) than are available!"; } rows = dims.get_height(first_comp_idx); cols = dims.get_width(first_comp_idx); is_signed = dims.get_signed(first_comp_idx); for (n=0; n < 3; n++, next_comp_idx++) { if ((rows != dims.get_height(next_comp_idx)) || (cols != dims.get_width(next_comp_idx)) || (is_signed != dims.get_signed(next_comp_idx))) { kdu_error e; e << "Can only write a PPM file with 3 image " "components, all having the same dimensions and the same " "signed/unsigned characteristics."; } precision[n] = dims.get_bit_depth(next_comp_idx); } if (is_signed) { kdu_warning w; w << "Signed sample values will be written to the " "PPM file as unsigned 8-bit quantities, centered about 128."; } if ((out = fopen(fname,"wb")) == NULL) { kdu_error e; e << "Unable to open output image file, \"" << fname <<"\"."; } fprintf(out,"P6\n%d %d\n255\n",cols,rows); incomplete_lines = NULL; free_lines = NULL; num_unwritten_rows = rows;}/*****************************************************************************//* ppm_out::~ppm_out *//*****************************************************************************/ppm_out::~ppm_out(){ if ((num_unwritten_rows > 0) || (incomplete_lines != NULL)) { kdu_warning w; w << "Not all rows of image components " << first_comp_idx << " through " << first_comp_idx+2 << " were completed!"; } image_line_buf *tmp; while ((tmp=incomplete_lines) != NULL) { incomplete_lines = tmp->next; delete tmp; } while ((tmp=free_lines) != NULL) { free_lines = tmp->next; delete tmp; } fclose(out);}/*****************************************************************************//* ppm_out::put *//*****************************************************************************/void ppm_out::put(int comp_idx, kdu_line_buf &line, int x_tnum){ int idx = comp_idx - this->first_comp_idx; assert((idx >= 0) && (idx <= 2)); x_tnum = x_tnum*3+idx; // Works so long as components written in order. image_line_buf *scan, *prev=NULL; for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next) { assert(scan->next_x_tnum >= x_tnum); if (scan->next_x_tnum == x_tnum) break; } if (scan == NULL) { // Need to open a new line buffer assert(x_tnum == 0); // Must consume in very specific order. if ((scan = free_lines) == NULL) scan = new image_line_buf(cols,3); free_lines = scan->next; if (prev == NULL) incomplete_lines = scan; else prev->next = scan; scan->accessed_samples = 0; scan->next_x_tnum = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -