📄 pluginjpeg.cpp
字号:
src->pub.term_source = term_source; src->infile = infile; src->m_io = &io; src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */}GLOBAL(void)jpeg_freeimage_dst (j_compress_ptr cinfo, fi_handle outfile, FreeImageIO &io) { freeimage_dst_ptr dest; if (cinfo->dest == NULL) { cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_destination_mgr)); } dest = (freeimage_dst_ptr) cinfo->dest; dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; dest->outfile = outfile; dest->m_io = &io;}// ==========================================================// Plugin Interface// ==========================================================static int s_format_id;// ==========================================================// Plugin Implementation// ==========================================================static const char * DLL_CALLCONVFormat() { return "JPEG";}static const char * DLL_CALLCONVDescription() { return "JPEG - JFIF Compliant";}static const char * DLL_CALLCONVExtension() { return "jpg,jif,jpeg";}static const char * DLL_CALLCONVRegExpr() { return "^\377\330\377";}static const char * DLL_CALLCONVMimeType() { return "image/jpeg";}static BOOL DLL_CALLCONVValidate(FreeImageIO &io, fi_handle handle) { BYTE jpeg_signature[] = { 0xFF, 0xD8 }; BYTE signature[2] = { 0, 0 }; io.read_proc(signature, 1, sizeof(jpeg_signature), handle); return (memcmp(jpeg_signature, signature, sizeof(jpeg_signature)) == 0);}// ----------------------------------------------------------static FIBITMAP * DLL_CALLCONVLoad(FreeImage &freeimage, FreeImageIO &io, fi_handle handle, int page, int flags, void *data) { if (handle) { FIBITMAP *dib = NULL; try { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; // Step 1: allocate and initialize JPEG decompression object cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = jpeg_error_exit; jerr.output_message = jpeg_output_message; jpeg_create_decompress(&cinfo); // Step 2: specify data source (eg, a handle) jpeg_freeimage_src(&cinfo, handle, io); // Step 3: read handle parameters with jpeg_read_header() jpeg_read_header(&cinfo, TRUE); // Step 4a: set parameters for decompression if ((flags != JPEG_ACCURATE)) { cinfo.dct_method = JDCT_IFAST; cinfo.do_fancy_upsampling = FALSE; } // Step 4b: allocate dib and init header dib = freeimage.allocate_proc(cinfo.image_width, cinfo.image_height, 8 * cinfo.num_components, 0xFF00, 0xFF, 0xFF0000); if (cinfo.num_components == 1) { RGBQUAD *colors = freeimage.get_palette_proc(dib); for (int i = 0; i < 256; i++) { colors[i].rgbRed = i; colors[i].rgbGreen = i; colors[i].rgbBlue = i; } } // Step 4c: handle metrices BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib); if (cinfo.density_unit == 1) { // dots/inch pInfoHeader->biXPelsPerMeter = (int) (((float)cinfo.X_density) / 0.0254000 + 0.5); pInfoHeader->biYPelsPerMeter = (int) (((float)cinfo.Y_density) / 0.0254000 + 0.5); } else if (cinfo.density_unit == 2) { // dots/cm pInfoHeader->biXPelsPerMeter = cinfo.X_density * 100; pInfoHeader->biYPelsPerMeter = cinfo.Y_density * 100; } // Step 5: start decompressor jpeg_start_decompress(&cinfo); // Step 6: while (scan lines remain to be read) jpeg_read_scanlines(...); while (cinfo.output_scanline < cinfo.output_height) { JSAMPROW b = freeimage.get_scanline_proc(dib, cinfo.output_height - cinfo.output_scanline - 1); jpeg_read_scanlines(&cinfo, &b, 1); } // Step 7: finish decompression jpeg_finish_decompress(&cinfo); // Step 8: release JPEG decompression object jpeg_destroy_decompress(&cinfo); return (FIBITMAP *)dib; } catch (...) { freeimage.unload_proc(dib); } } return NULL;}static BOOL DLL_CALLCONVSave(FreeImage &freeimage, FreeImageIO &io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) { if ((dib) && (handle)) { try { // Check dib format WORD bpp = freeimage.get_bpp_proc(dib); if ((bpp == 32) && (freeimage.is_transparent_proc(dib))) throw "JPEG does not support alpha channels"; else if (((bpp != 24) && (bpp != 32)) && (!((bpp == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)))) throw "only 24-bit highcolor or 8-bit greyscale bitmaps can be saved as JPEG"; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; // Step 1: allocate and initialize JPEG compression object cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = jpeg_error_exit; jerr.output_message = jpeg_output_message; /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&cinfo); /* Step 2: specify data destination (eg, a file) */ jpeg_freeimage_dst(&cinfo, handle, io); /* Step 3: set parameters for compression */ cinfo.image_width = freeimage.get_width_proc(dib); cinfo.image_height = freeimage.get_height_proc(dib); switch(FreeImage_GetColorType(dib)) { case FIC_MINISBLACK : cinfo.in_color_space = JCS_GRAYSCALE; cinfo.input_components = 1; break; default : cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3; break; } jpeg_set_defaults(&cinfo); // Set JFIF density parameters from the DIB data BITMAPINFOHEADER *pInfoHeader = freeimage.get_info_header_proc(dib); cinfo.X_density = (WORD)(pInfoHeader->biXPelsPerMeter / 100.0F + 0.5); cinfo.Y_density = (WORD)(pInfoHeader->biYPelsPerMeter / 100.0F + 0.5); cinfo.density_unit = 2; // dots / cm // Step 4: set quality // the first 7 bits are reserved for low level quality settings // the other bits are high level (i.e. enum-ish) int quality; if ((flags & JPEG_QUALITYBAD) == JPEG_QUALITYBAD) { quality = 10; } else if ((flags & JPEG_QUALITYAVERAGE) == JPEG_QUALITYAVERAGE) { quality = 25; } else if ((flags & JPEG_QUALITYNORMAL) == JPEG_QUALITYNORMAL) { quality = 50; } else if ((flags & JPEG_QUALITYGOOD) == JPEG_QUALITYGOOD) { quality = 75; } else if ((flags & JPEG_QUALITYSUPERB) == JPEG_QUALITYSUPERB) { quality = 100; } else { if ((flags & 0x7F) == 0) { quality = 75; } else { quality = flags & 0x7F; } } jpeg_set_quality(&cinfo, quality, TRUE); /* limit to baseline-JPEG values */ /* Step 5: Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Step 6: while (scan lines remain to be written) */ if (freeimage.get_bpp_proc(dib) == 32) { int pitch = CalculatePitch(CalculateLine(freeimage.get_width_proc(dib), 24)); JSAMPROW b = (BYTE *)malloc(pitch); for (unsigned i = 0; i < freeimage.get_height_proc(dib); ++i) { freeimage.convert_line_32to24_proc(b, freeimage.get_scanline_proc(dib, freeimage.get_height_proc(dib) - cinfo.next_scanline - 1), freeimage.get_width_proc(dib)); jpeg_write_scanlines(&cinfo, &b, 1); } free(b); } else { while (cinfo.next_scanline < cinfo.image_height) { JSAMPROW b = freeimage.get_scanline_proc(dib, freeimage.get_height_proc(dib) - cinfo.next_scanline - 1); jpeg_write_scanlines(&cinfo, &b, 1); } } /* Step 7: Finish compression */ jpeg_finish_compress(&cinfo); /* Step 8: release JPEG compression object */ jpeg_destroy_compress(&cinfo); return TRUE; } catch (char *text) { freeimage.output_message_proc(s_format_id, text); return FALSE; } catch (FREE_IMAGE_FORMAT) { return FALSE; } } return FALSE;}// ==========================================================// Init// ==========================================================void DLL_CALLCONVInitJPEG(Plugin &plugin, int format_id) { s_format_id = format_id; plugin.format_proc = Format; plugin.description_proc = Description; plugin.extension_proc = Extension; plugin.regexpr_proc = RegExpr; plugin.load_proc = Load; plugin.save_proc = Save; plugin.validate_proc = Validate; plugin.mime_proc = MimeType;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -