//-------------------------------------------------------- // open a GIF file to be read BOOL mgGIFRead::open( const char* fileName) // name of file to open { // if file name exists m_inFile = mgOSFileOpen(fileName, "rb"); if (m_inFile == NULL) throw new mgErrorMsg("imgBadOpen", "", ""); // Figure out the input file format, and set up to read it. m_srcMgr = jinit_read_gif(&m_CompInfo); m_srcMgr->input_file = m_inFile; // Read the input file header to obtain file size & colorspace. (*m_srcMgr->start_input) (&m_CompInfo, m_srcMgr); (*m_CompInfo.mem->realize_virt_arrays) ((j_common_ptr) &m_CompInfo); m_width = m_CompInfo.image_width; m_height = m_CompInfo.image_height; m_RGBAline = new BYTE[m_CompInfo.image_width * 4]; if (!m_writer->outputStart(m_CompInfo.image_width, m_CompInfo.image_height)) return false; return true; }
select_file_type (j_compress_ptr cinfo, FILE * infile) { int c; if (is_targa) { #ifdef TARGA_SUPPORTED return jinit_read_targa(cinfo); #else ERREXIT(cinfo, JERR_TGA_NOTCOMP); #endif } if ((c = getc(infile)) == EOF) ERREXIT(cinfo, JERR_INPUT_EMPTY); if (ungetc(c, infile) == EOF) ERREXIT(cinfo, JERR_UNGETC_FAILED); switch (c) { #ifdef BMP_SUPPORTED case 'B': return jinit_read_bmp(cinfo); #endif #ifdef GIF_SUPPORTED case 'G': return jinit_read_gif(cinfo); #endif #ifdef PPM_SUPPORTED case 'P': return jinit_read_ppm(cinfo); #endif #ifdef PNG_SUPPORTED case 0x89: return jinit_read_png(cinfo); #endif #ifdef RLE_SUPPORTED case 'R': return jinit_read_rle(cinfo); #endif #ifdef TARGA_SUPPORTED case 0x00: return jinit_read_targa(cinfo); #endif case 0xff: is_jpeg = TRUE; return jinit_read_jpeg(cinfo); default: ERREXIT(cinfo, JERR_UNKNOWN_FORMAT); break; } return NULL; /* suppress compiler warnings */ }
DistillerStatus DistillerMain(Argument *args, int nargs, DistillerInput *din, DistillerOutput *dout) { JSAMPROW handoff = NULL; JDIMENSION handoff_height, handoff_width, num_scanlines; int max_x=-1, max_y=-1, min_x=-1, min_y=-1, qual=55, i; int expert=0, resize=0, quality=3, nodistill=0, ismap=0; double scale = 0.5; cjpeg_source_ptr src_mgr; void *phase1_data; INT32 phase1_length; int fin_denom, fin_qual; DistillerStatus result = distBadInput; SetData(dout, NULL); bailout_now = 0; if ( (setjmp(jumpbuffer) != 0) ) { /* * fatal error occurred, so return immediately. */ MonitorClientSend(monID, "Distiller Errors", "Resetting distiller...\n", "Log"); DistillerExit(); DistillerInit(dType, 0, NULL); if (DataPtr(dout) != NULL) DataNeedsFree(dout,gm_True); else DataNeedsFree(dout,gm_False); return distFatalError; } /* * parse distillation arguments. set default values for some * things, then override them if args are specified. Default will * be to scale each axis by 0.5, turn quality down to 55%. */ for (i=0; i<nargs; i++) { INT32 argval = ARG_INT(args[i]); switch(ARG_ID(args[i])) { case GJPG_MAX_X: max_x = (int) argval; break; case GJPG_MAX_Y: max_y = (int) argval; break; case GJPG_MIN_X: min_x = (int) argval; break; case GJPG_MIN_Y: min_y = (int) argval; break; case GJPG_SCALE: scale = (double) ARG_DOUBLE(args[i]); break; case GJPG_QUAL: qual = (int) argval; break; case FRONT_RESIZE: resize = (int) argval; break; case FRONT_NO_DISTILL: nodistill = (int) argval; break; case FRONT_QUALITY: if (argval >= 1 && argval <= 5) quality = (int) argval; break; case FRONT_EXPERT: expert = (int) argval; break; case FRONT_ISMAP: ismap = (int) argval; break; default: break; } } if (nodistill) { return gjpg_passthrough(din, dout); } /* First pass through, we're just going to convert the GIF to JPEG */ phase1_data = NULL; phase1_length = 0; dstinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&dstinfo); src_mgr = jinit_read_gif(&dstinfo, (JOCTET *) DataPtr(din), (INT32) DataLength(din)); (*src_mgr->start_input)(&dstinfo, src_mgr); jpeg_default_colorspace(&dstinfo); jpeg_mem_dest(&dstinfo, (void **) &phase1_data, (UINT32 *) &phase1_length); jpeg_start_compress(&dstinfo, TRUE); while (dstinfo.next_scanline < dstinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows)(&dstinfo, src_mgr); jpeg_write_scanlines(&dstinfo, src_mgr->buffer, num_scanlines); } (*src_mgr->finish_input)(&dstinfo, src_mgr); jpeg_finish_compress(&dstinfo); /* early bailout because of animated or transparent gif? */ if (bailout_now && DataLength(din) <= bailout_thresh[quality]) { result = distBadInput; goto JPGMUNGE_RETURN; } /* Now we're into the second pass. Let's do our JPEG->JPEG * distillation. We need to compute the denominator and the quality * knob setting. */ if (expert) { /* Do expert-like things here. Need to work out still. */ fin_qual = qual; fin_denom = compute_scale_denom(max_x, max_y, min_x, min_y, srcinfo.image_width, srcinfo.image_height, scale); } else { /* We're in beginner mode. Life is easier. */ if (ismap) { fin_qual = ismap_qual[quality-1]; fin_denom = ismap_denom[quality-1]; } else if (resize) { fin_qual = noscale_qual[quality-1]; fin_denom = noscale_denom[quality-1]; } else { fin_qual = norm_qual[quality-1]; fin_denom = norm_denom[quality-1]; } } /* Prep the input decompressor */ jpeg_mem_src(&srcinfo, phase1_data, phase1_length); jpeg_read_header(&srcinfo, TRUE); srcinfo.scale_num = 1; srcinfo.scale_denom = fin_denom; srcinfo.dither_mode = JDITHER_ORDERED; srcinfo.dct_method = JDCT_FASTEST; jpeg_start_decompress(&srcinfo); /* Prep the output compressor */ SetDataLength(dout,0); SetData(dout, NULL); sprintf(dout->mimeType, "image/jpeg"); jpeg_mem_dest(&dstinfo, (void **) &(DataPtr(dout)), (UINT32 *) &(DataLength(dout))); dstinfo.image_width = srcinfo.output_width; dstinfo.image_height = srcinfo.output_height; dstinfo.input_components = srcinfo.output_components; dstinfo.in_color_space = srcinfo.out_color_space; jpeg_set_defaults(&dstinfo); jpeg_set_quality(&dstinfo, fin_qual, TRUE); jpeg_start_compress(&dstinfo, TRUE); handoff_height = (JDIMENSION) 1; handoff_width = srcinfo.output_width*sizeof(JSAMPLE)*srcinfo.output_components; handoff = (JSAMPROW) malloc(handoff_width); /* We're going to need some buffer space to hand off data from the decompressor to the compressor. */ while (srcinfo.output_scanline < srcinfo.output_height) { num_scanlines = jpeg_read_scanlines(&srcinfo, &handoff, handoff_height); jpeg_write_scanlines(&dstinfo, &handoff, num_scanlines); } jpeg_finish_decompress(&srcinfo); jpeg_finish_compress(&dstinfo); result = distOk; JPGMUNGE_RETURN: if (handoff) free(handoff); DataNeedsFree(dout,gm_True); if (phase1_data) free(phase1_data); if (DataLength(dout) > DataLength(din)) { SetDataLength(dout, DataLength(din)); memcpy(DataPtr(dout), DataPtr(din), DataLength(din)); sprintf(dout->mimeType, "image/gif"); } DEBUG("finished processing\n"); return result; }