Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
rdrle.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "cdjpeg.h"
00023
00024 #ifdef RLE_SUPPORTED
00025
00026
00027
00028 #include <rle.h>
00029
00030
00031
00032
00033
00034
00035 #if BITS_IN_JSAMPLE != 8
00036 Sorry, this code only copes with 8-bit JSAMPLEs.
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 typedef enum
00052 { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 typedef struct _rle_source_struct * rle_source_ptr;
00063
00064 typedef struct _rle_source_struct {
00065 struct cjpeg_source_struct pub;
00066
00067 rle_kind visual;
00068 jvirt_sarray_ptr image;
00069 JDIMENSION row;
00070 rle_hdr header;
00071 rle_pixel** rle_row;
00072
00073 } rle_source_struct;
00074
00075
00076
00077
00078
00079
00080 METHODDEF(void)
00081 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00082 {
00083 rle_source_ptr source = (rle_source_ptr) sinfo;
00084 JDIMENSION width, height;
00085 #ifdef PROGRESS_REPORT
00086 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00087 #endif
00088
00089
00090 source->header = *rle_hdr_init(NULL);
00091 source->header.rle_file = source->pub.input_file;
00092 switch (rle_get_setup(&(source->header))) {
00093 case RLE_SUCCESS:
00094
00095 break;
00096 case RLE_NOT_RLE:
00097 ERREXIT(cinfo, JERR_RLE_NOT);
00098 break;
00099 case RLE_NO_SPACE:
00100 ERREXIT(cinfo, JERR_RLE_MEM);
00101 break;
00102 case RLE_EMPTY:
00103 ERREXIT(cinfo, JERR_RLE_EMPTY);
00104 break;
00105 case RLE_EOF:
00106 ERREXIT(cinfo, JERR_RLE_EOF);
00107 break;
00108 default:
00109 ERREXIT(cinfo, JERR_RLE_BADERROR);
00110 break;
00111 }
00112
00113
00114
00115 width = source->header.xmax - source->header.xmin + 1;
00116 height = source->header.ymax - source->header.ymin + 1;
00117 source->header.xmin = 0;
00118 source->header.xmax = width-1;
00119
00120 cinfo->image_width = width;
00121 cinfo->image_height = height;
00122 cinfo->data_precision = 8;
00123
00124 if (source->header.ncolors == 1 && source->header.ncmap == 0) {
00125 source->visual = GRAYSCALE;
00126 TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height);
00127 } else if (source->header.ncolors == 1 && source->header.ncmap == 1) {
00128 source->visual = MAPPEDGRAY;
00129 TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height,
00130 1 << source->header.cmaplen);
00131 } else if (source->header.ncolors == 1 && source->header.ncmap == 3) {
00132 source->visual = PSEUDOCOLOR;
00133 TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height,
00134 1 << source->header.cmaplen);
00135 } else if (source->header.ncolors == 3 && source->header.ncmap == 3) {
00136 source->visual = TRUECOLOR;
00137 TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height,
00138 1 << source->header.cmaplen);
00139 } else if (source->header.ncolors == 3 && source->header.ncmap == 0) {
00140 source->visual = DIRECTCOLOR;
00141 TRACEMS2(cinfo, 1, JTRC_RLE, width, height);
00142 } else
00143 ERREXIT(cinfo, JERR_RLE_UNSUPPORTED);
00144
00145 if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) {
00146 cinfo->in_color_space = JCS_GRAYSCALE;
00147 cinfo->input_components = 1;
00148 } else {
00149 cinfo->in_color_space = JCS_RGB;
00150 cinfo->input_components = 3;
00151 }
00152
00153
00154
00155
00156
00157 if (source->visual != GRAYSCALE) {
00158 source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray)
00159 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00160 (JDIMENSION) width, (JDIMENSION) cinfo->input_components);
00161 }
00162
00163
00164 source->image = (*cinfo->mem->request_virt_sarray)
00165 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
00166 (JDIMENSION) (width * source->header.ncolors),
00167 (JDIMENSION) height, (JDIMENSION) 1);
00168
00169 #ifdef PROGRESS_REPORT
00170 if (progress != NULL) {
00171
00172 progress->total_extra_passes++;
00173 }
00174 #endif
00175
00176 source->pub.buffer_height = 1;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 METHODDEF(JDIMENSION)
00187 get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00188 {
00189 rle_source_ptr source = (rle_source_ptr) sinfo;
00190
00191 source->row--;
00192 source->pub.buffer = (*cinfo->mem->access_virt_sarray)
00193 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00194
00195 return 1;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 METHODDEF(JDIMENSION)
00205 get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00206 {
00207 rle_source_ptr source = (rle_source_ptr) sinfo;
00208 JSAMPROW src_row, dest_row;
00209 JDIMENSION col;
00210 rle_map *colormap;
00211 int val;
00212
00213 colormap = source->header.cmap;
00214 dest_row = source->pub.buffer[0];
00215 source->row--;
00216 src_row = * (*cinfo->mem->access_virt_sarray)
00217 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00218
00219 for (col = cinfo->image_width; col > 0; col--) {
00220 val = GETJSAMPLE(*src_row++);
00221 *dest_row++ = (JSAMPLE) (colormap[val ] >> 8);
00222 *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8);
00223 *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8);
00224 }
00225
00226 return 1;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 METHODDEF(JDIMENSION)
00241 load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00242 {
00243 rle_source_ptr source = (rle_source_ptr) sinfo;
00244 JDIMENSION row, col;
00245 JSAMPROW scanline, red_ptr, green_ptr, blue_ptr;
00246 rle_pixel **rle_row;
00247 rle_map *colormap;
00248 char channel;
00249 #ifdef PROGRESS_REPORT
00250 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00251 #endif
00252
00253 colormap = source->header.cmap;
00254 rle_row = source->rle_row;
00255
00256
00257
00258
00259
00260 RLE_CLR_BIT(source->header, RLE_ALPHA);
00261
00262 #ifdef PROGRESS_REPORT
00263 if (progress != NULL) {
00264 progress->pub.pass_limit = cinfo->image_height;
00265 progress->pub.pass_counter = 0;
00266 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00267 }
00268 #endif
00269
00270 switch (source->visual) {
00271
00272 case GRAYSCALE:
00273 case PSEUDOCOLOR:
00274 for (row = 0; row < cinfo->image_height; row++) {
00275 rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
00276 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00277 rle_getrow(&source->header, rle_row);
00278 #ifdef PROGRESS_REPORT
00279 if (progress != NULL) {
00280 progress->pub.pass_counter++;
00281 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00282 }
00283 #endif
00284 }
00285 break;
00286
00287 case MAPPEDGRAY:
00288 case TRUECOLOR:
00289 for (row = 0; row < cinfo->image_height; row++) {
00290 scanline = * (*cinfo->mem->access_virt_sarray)
00291 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00292 rle_row = source->rle_row;
00293 rle_getrow(&source->header, rle_row);
00294
00295 for (col = 0; col < cinfo->image_width; col++) {
00296 for (channel = 0; channel < source->header.ncolors; channel++) {
00297 *scanline++ = (JSAMPLE)
00298 (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
00299 }
00300 }
00301
00302 #ifdef PROGRESS_REPORT
00303 if (progress != NULL) {
00304 progress->pub.pass_counter++;
00305 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00306 }
00307 #endif
00308 }
00309 break;
00310
00311 case DIRECTCOLOR:
00312 for (row = 0; row < cinfo->image_height; row++) {
00313 scanline = * (*cinfo->mem->access_virt_sarray)
00314 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00315 rle_getrow(&source->header, rle_row);
00316
00317 red_ptr = rle_row[0];
00318 green_ptr = rle_row[1];
00319 blue_ptr = rle_row[2];
00320
00321 for (col = cinfo->image_width; col > 0; col--) {
00322 *scanline++ = *red_ptr++;
00323 *scanline++ = *green_ptr++;
00324 *scanline++ = *blue_ptr++;
00325 }
00326
00327 #ifdef PROGRESS_REPORT
00328 if (progress != NULL) {
00329 progress->pub.pass_counter++;
00330 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00331 }
00332 #endif
00333 }
00334 }
00335
00336 #ifdef PROGRESS_REPORT
00337 if (progress != NULL)
00338 progress->completed_extra_passes++;
00339 #endif
00340
00341
00342 if (source->visual == PSEUDOCOLOR) {
00343 source->pub.buffer = source->rle_row;
00344 source->pub.get_pixel_rows = get_pseudocolor_row;
00345 } else {
00346 source->pub.get_pixel_rows = get_rle_row;
00347 }
00348 source->row = cinfo->image_height;
00349
00350
00351 return (*source->pub.get_pixel_rows) (cinfo, sinfo);
00352 }
00353
00354
00355
00356
00357
00358
00359 METHODDEF(void)
00360 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00361 {
00362
00363 }
00364
00365
00366
00367
00368
00369
00370 GLOBAL(cjpeg_source_ptr)
00371 jinit_read_rle (j_compress_ptr cinfo)
00372 {
00373 rle_source_ptr source;
00374
00375
00376 source = (rle_source_ptr)
00377 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00378 SIZEOF(rle_source_struct));
00379
00380 source->pub.start_input = start_input_rle;
00381 source->pub.finish_input = finish_input_rle;
00382 source->pub.get_pixel_rows = load_image;
00383
00384 return (cjpeg_source_ptr) source;
00385 }
00386
00387 #endif