1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/PTdecode/CImg-1.3.0/plugins/jpeg_buffer.h Mon Aug 03 14:09:20 2009 +0100 1.3 @@ -0,0 +1,367 @@ 1.4 +/* 1.5 + # 1.6 + # File : deprecated.h 1.7 + # ( C++ header file - CImg plug-in ) 1.8 + # 1.9 + # Description : This CImg plug-in provide functions to load and save jpeg images 1.10 + # directly from/to memory buffers of JOCTET buffers, using the 1.11 + # JPEG library (required to compile !) 1.12 + # This file is a part of the CImg Library project. 1.13 + # ( http://cimg.sourceforge.net ) 1.14 + # 1.15 + # Copyright : Paolo Prete 1.16 + # ( p4olo_prete@yahoo.it ) 1.17 + # 1.18 + # License : CeCILL v2.0 1.19 + # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html ) 1.20 + # 1.21 + # This software is governed by the CeCILL license under French law and 1.22 + # abiding by the rules of distribution of free software. You can use, 1.23 + # modify and/ or redistribute the software under the terms of the CeCILL 1.24 + # license as circulated by CEA, CNRS and INRIA at the following URL 1.25 + # "http://www.cecill.info". 1.26 + # 1.27 + # As a counterpart to the access to the source code and rights to copy, 1.28 + # modify and redistribute granted by the license, users are provided only 1.29 + # with a limited warranty and the software's author, the holder of the 1.30 + # economic rights, and the successive licensors have only limited 1.31 + # liability. 1.32 + # 1.33 + # In this respect, the user's attention is drawn to the risks associated 1.34 + # with loading, using, modifying and/or developing or reproducing the 1.35 + # software by the user in light of its specific status of free software, 1.36 + # that may mean that it is complicated to manipulate, and that also 1.37 + # therefore means that it is reserved for developers and experienced 1.38 + # professionals having in-depth computer knowledge. Users are therefore 1.39 + # encouraged to load and test the software's suitability as regards their 1.40 + # requirements in conditions enabling the security of their systems and/or 1.41 + # data to be ensured and, more generally, to use and operate it in the 1.42 + # same conditions as regards security. 1.43 + # 1.44 + # The fact that you are presently reading this means that you have had 1.45 + # knowledge of the CeCILL license and that you accept its terms. 1.46 + # 1.47 +*/ 1.48 + 1.49 +/*----------------------------------------------------------------------------------- 1.50 + 1.51 + IMPORTANT NOTE : 1.52 + 1.53 + You *need* to include the following two lines in your own code to use this plugin : 1.54 + 1.55 + #include <cstdio> 1.56 + #include <jpeglib.h> 1.57 + #include <jerror.h> 1.58 + 1.59 + (see example file provided in examples/jpeg_buffer.cpp). 1.60 + 1.61 +------------------------------------------------------------------------------------*/ 1.62 + 1.63 +/////////////////////////////////////////////////////////////////////////////////////// 1.64 +// 1.65 +// extension of libjpeg (helper functions for loading images from JOCTET arrays) 1.66 +// hacked from 1.67 +// http://www.koders.com/cpp/fidB5A4549ABB5CB01824058F57A43D095D3F95AB40.aspx 1.68 +// 1.69 +/////////////////////////////////////////////////////////////////////////////////////// 1.70 + 1.71 +#define INPUT_BUF_SIZE 4096 1.72 + 1.73 +struct my_source_mem { 1.74 + struct jpeg_source_mgr pub; // Public fields 1.75 + int indexinmem; 1.76 + JOCTET * inmem; // Source stream 1.77 + JOCTET * buffer; // Start of buffer 1.78 + int lenght; // Size of buffer in memory 1.79 + boolean start_of_file; // Have we gotten any data yet? 1.80 +}; 1.81 + 1.82 +struct my_source_mgr { 1.83 + struct jpeg_source_mgr pub; // public fields 1.84 + FILE * infile; // source stream 1.85 + JOCTET * buffer; // start of buffer 1.86 + boolean start_of_file; // have we gotten any data yet? 1.87 +}; 1.88 + 1.89 +typedef my_source_mem *my_src_mptr; 1.90 +typedef my_source_mgr *my_src_ptr; 1.91 + 1.92 +static boolean fill_minput_buffer(j_decompress_ptr cinfo) { 1.93 + my_src_mptr src = (my_src_mptr) cinfo->src; 1.94 + size_t nbytes; 1.95 + if (src->indexinmem+INPUT_BUF_SIZE>src->lenght) nbytes=src->lenght-src->indexinmem; 1.96 + else nbytes = INPUT_BUF_SIZE; 1.97 + std::memcpy(src->buffer,src->inmem,nbytes); 1.98 + src->inmem += nbytes; 1.99 + src->indexinmem += (int)nbytes; 1.100 + src->pub.next_input_byte = src->buffer; 1.101 + src->pub.bytes_in_buffer = INPUT_BUF_SIZE; 1.102 + src->start_of_file = FALSE; 1.103 + return TRUE; 1.104 +} 1.105 + 1.106 +static void skip_minput_data(j_decompress_ptr cinfo, long num_bytes) { 1.107 + my_src_ptr src = (my_src_ptr)cinfo->src; 1.108 + if (num_bytes > 0) { 1.109 + while (num_bytes > (long) src->pub.bytes_in_buffer) { 1.110 + num_bytes -= (long) src->pub.bytes_in_buffer; 1.111 + fill_minput_buffer(cinfo); 1.112 + // note we assume that fill_input_buffer will never return FALSE, 1.113 + // so suspension need not be handled. 1.114 + // 1.115 + } 1.116 + src->pub.next_input_byte += (size_t) num_bytes; 1.117 + src->pub.bytes_in_buffer -= (size_t) num_bytes; 1.118 + } 1.119 +} 1.120 + 1.121 +static void init_msource(j_decompress_ptr cinfo) { 1.122 + my_src_mptr src = (my_src_mptr)cinfo->src; 1.123 + src->start_of_file = TRUE; 1.124 +} 1.125 + 1.126 +static void term_source(j_decompress_ptr) { 1.127 + // no work necessary here 1.128 +} 1.129 + 1.130 +static void jpeg_mem_src(j_decompress_ptr cinfo, JOCTET * memptr,int lenght) { 1.131 + my_src_mptr src; 1.132 + 1.133 + // The source object and input buffer are made permanent so that a series 1.134 + //of JPEG images can be read from the same file by calling jpeg_stdio_src 1.135 + // only before the first one. (If we discarded the buffer at the end of 1.136 + // one image, we'd likely lose the start of the next one.) 1.137 + // This makes it unsafe to use this manager and a different source 1.138 + // manager serially with the same JPEG object. Caveat programmer. 1.139 + // 1.140 + 1.141 + // first time for this JPEG object? 1.142 + if (cinfo->src == NULL) { 1.143 + cinfo->src = (struct jpeg_source_mgr*)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,sizeof(my_source_mem)); 1.144 + src = (my_src_mptr) cinfo->src; 1.145 + src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,INPUT_BUF_SIZE * sizeof(JOCTET)); 1.146 + } 1.147 + 1.148 + src = (my_src_mptr) cinfo->src; 1.149 + src->pub.init_source = init_msource; 1.150 + src->pub.fill_input_buffer = fill_minput_buffer; 1.151 + src->pub.skip_input_data = skip_minput_data; 1.152 + //src->pub.resync_to_restart = jpeg_resync_to_restart; // use default method 1.153 + src->pub.term_source = term_source; 1.154 + src->inmem = memptr; 1.155 + src->indexinmem = 0; 1.156 + src->lenght = lenght; 1.157 + src->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read 1.158 + src->pub.next_input_byte = NULL; // until buffer loaded 1.159 +} 1.160 + 1.161 +// The following declarations and 5 functions are jpeg related 1.162 +// functions used by put_jpeg_grey_memory and put_jpeg_yuv420p_memory 1.163 +// 1.164 +struct mem_destination_mgr { 1.165 + struct jpeg_destination_mgr pub; 1.166 + JOCTET *buf; 1.167 + size_t bufsize; 1.168 + size_t jpegsize; 1.169 +}; 1.170 + 1.171 +typedef mem_destination_mgr *mem_dest_ptr; 1.172 + 1.173 +static void init_destination(j_compress_ptr cinfo) { 1.174 + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; 1.175 + dest->pub.next_output_byte = dest->buf; 1.176 + dest->pub.free_in_buffer = dest->bufsize; 1.177 + dest->jpegsize = 0; 1.178 +} 1.179 + 1.180 +static boolean empty_output_buffer(j_compress_ptr cinfo) { 1.181 + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; 1.182 + dest->pub.next_output_byte = dest->buf; 1.183 + dest->pub.free_in_buffer = dest->bufsize; 1.184 + return FALSE; 1.185 + ERREXIT(cinfo, JERR_BUFFER_SIZE); 1.186 +} 1.187 + 1.188 +static void term_destination(j_compress_ptr cinfo) { 1.189 + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; 1.190 + dest->jpegsize = dest->bufsize - dest->pub.free_in_buffer; 1.191 +} 1.192 + 1.193 +static void jpeg_mem_dest(j_compress_ptr cinfo, JOCTET* buf, size_t bufsize) { 1.194 + mem_dest_ptr dest; 1.195 + if (cinfo->dest == NULL) { 1.196 + cinfo->dest = (struct jpeg_destination_mgr *) 1.197 + (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,sizeof(mem_destination_mgr)); 1.198 + } 1.199 + dest = (mem_dest_ptr) cinfo->dest; 1.200 + dest->pub.init_destination = init_destination; 1.201 + dest->pub.empty_output_buffer = empty_output_buffer; 1.202 + dest->pub.term_destination = term_destination; 1.203 + dest->buf = buf; 1.204 + dest->bufsize = bufsize; 1.205 + dest->jpegsize = 0; 1.206 +} 1.207 + 1.208 +static unsigned jpeg_mem_size(j_compress_ptr cinfo) { 1.209 + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; 1.210 + return dest->jpegsize; 1.211 +} 1.212 + 1.213 +///////////////////////////////////////////////////////////////// 1.214 +// 1.215 +// Define main CImg plugin functions. 1.216 +// (you should use these functions only in your own code) 1.217 +// 1.218 +///////////////////////////////////////////////////////////////// 1.219 + 1.220 +//! Load image from a jpeg-coded memory buffer. 1.221 +/** 1.222 + \param buffer Memory buffer containing the jpeg-coded image data. 1.223 + \param buffer_size Size of the memory buffer, in bytes. 1.224 +**/ 1.225 +static CImg get_load_jpeg_buffer(const JOCTET *const buffer, const unsigned buffer_size) { 1.226 + struct jpeg_decompress_struct cinfo; 1.227 + struct jpeg_error_mgr jerr; 1.228 + cinfo.err = jpeg_std_error(&jerr); 1.229 + jpeg_create_decompress(&cinfo); 1.230 + jpeg_mem_src(&cinfo, const_cast<JOCTET*>(buffer), buffer_size); 1.231 + jpeg_read_header(&cinfo,TRUE); 1.232 + jpeg_start_decompress(&cinfo); 1.233 + 1.234 + const unsigned int row_stride = cinfo.output_width * cinfo.output_components; 1.235 + JOCTET *buf = new JOCTET[cinfo.output_width*cinfo.output_height*cinfo.output_components]; 1.236 + const JOCTET *buf2 = buf; 1.237 + JSAMPROW row_pointer[1]; 1.238 + while (cinfo.output_scanline < cinfo.output_height) { 1.239 + row_pointer[0] = buf + cinfo.output_scanline*row_stride; 1.240 + jpeg_read_scanlines(&cinfo,row_pointer,1); 1.241 + } 1.242 + jpeg_finish_decompress(&cinfo); 1.243 + jpeg_destroy_decompress(&cinfo); 1.244 + 1.245 + CImg<T> dest(cinfo.output_width,cinfo.output_height,1,cinfo.output_components); 1.246 + switch (dest.dim) { 1.247 + case 1: { 1.248 + T *ptr_g = dest.ptr(0,0,0,0); 1.249 + cimg_foroff(dest,off) *(ptr_g++) = (T)*(buf2++); 1.250 + } break; 1.251 + case 3: { 1.252 + T 1.253 + *ptr_r = dest.ptr(0,0,0,0), 1.254 + *ptr_g = dest.ptr(0,0,0,1), 1.255 + *ptr_b = dest.ptr(0,0,0,2); 1.256 + cimg_forXY(dest,x,y) { 1.257 + *(ptr_r++) = (T)*(buf2++); 1.258 + *(ptr_g++) = (T)*(buf2++); 1.259 + *(ptr_b++) = (T)*(buf2++); 1.260 + } 1.261 + } break; 1.262 + case 4: { 1.263 + T 1.264 + *ptr_r = dest.ptr(0,0,0,0), 1.265 + *ptr_g = dest.ptr(0,0,0,1), 1.266 + *ptr_b = dest.ptr(0,0,0,2), 1.267 + *ptr_a = dest.ptr(0,0,0,3); 1.268 + cimg_forXY(dest,x,y) { 1.269 + *(ptr_r++) = (T)*(buf2++); 1.270 + *(ptr_g++) = (T)*(buf2++); 1.271 + *(ptr_b++) = (T)*(buf2++); 1.272 + *(ptr_a++) = (T)*(buf2++); 1.273 + } 1.274 + } break; 1.275 + } 1.276 + delete[] buf; 1.277 + 1.278 + return dest; 1.279 +} 1.280 + 1.281 +//! Load image from a jpeg-coded memory buffer (in-place version) 1.282 +/** 1.283 + \param buffer Memory buffer containing the jpeg-coded image data. 1.284 + \param buffer_size Size of the memory buffer, in bytes. 1.285 +**/ 1.286 +CImg& load_jpeg_buffer(const JOCTET *const buffer, const unsigned buffer_size) { 1.287 + return get_load_jpeg_buffer(buffer,buffer_size).transfer_to(*this); 1.288 +} 1.289 + 1.290 +//! Save image in a memory buffer, directly as a jpeg-coded file 1.291 +/** 1.292 + \param buffer Memory buffer that will be written with the jpeg-coded image data. 1.293 + \param buffer_size Initial size of the memory buffer. When the function returns, the variable 1.294 + contains the effective length needed to fill the buffer. 1.295 + \param quality Quality of the jpeg compression. 1.296 +**/ 1.297 +const CImg& save_jpeg_buffer(JOCTET *const buffer, unsigned int &buffer_size, const int quality=100) const { 1.298 + 1.299 + // Fill pixel buffer 1.300 + JOCTET *buf; 1.301 + unsigned int dimbuf=0; 1.302 + J_COLOR_SPACE colortype=JCS_RGB; 1.303 + switch (dim) { 1.304 + case 1: { 1.305 + // Greyscale images 1.306 + JOCTET *buf2 = buf = new JOCTET[width*height*(dimbuf=1)]; 1.307 + const T 1.308 + *ptr_g = ptr(); 1.309 + colortype = JCS_GRAYSCALE; 1.310 + cimg_foroff(*this,off) *(buf2++) = (JOCTET)*(ptr_g++); 1.311 + } break; 1.312 + case 2: 1.313 + case 3: { 1.314 + // RGB images 1.315 + JOCTET *buf2 = buf = new JOCTET[width*height*(dimbuf=3)]; 1.316 + const T 1.317 + *ptr_r = ptr(0,0,0,0), 1.318 + *ptr_g = ptr(0,0,0,1), 1.319 + *ptr_b = ptr(0,0,0,dim>2?2:0); 1.320 + colortype = JCS_RGB; 1.321 + cimg_forXY(*this,x,y) { 1.322 + *(buf2++) = (JOCTET)*(ptr_r++); 1.323 + *(buf2++) = (JOCTET)*(ptr_g++); 1.324 + *(buf2++) = (JOCTET)*(ptr_b++); 1.325 + } 1.326 + } break; 1.327 + default: { 1.328 + // YCMYK images 1.329 + JOCTET *buf2 = buf = new JOCTET[width*height*(dimbuf=4)]; 1.330 + const T 1.331 + *ptr_r = ptr(0,0,0,0), 1.332 + *ptr_g = ptr(0,0,0,1), 1.333 + *ptr_b = ptr(0,0,0,2), 1.334 + *ptr_a = ptr(0,0,0,3); 1.335 + colortype = JCS_CMYK; 1.336 + cimg_forXY(*this,x,y) { 1.337 + *(buf2++) = (JOCTET)*(ptr_r++); 1.338 + *(buf2++) = (JOCTET)*(ptr_g++); 1.339 + *(buf2++) = (JOCTET)*(ptr_b++); 1.340 + *(buf2++) = (JOCTET)*(ptr_a++); 1.341 + } 1.342 + } break; 1.343 + } 1.344 + 1.345 + // Call libjpeg functions 1.346 + struct jpeg_compress_struct cinfo; 1.347 + struct jpeg_error_mgr jerr; 1.348 + cinfo.err = jpeg_std_error(&jerr); 1.349 + jpeg_create_compress(&cinfo); 1.350 + jpeg_mem_dest(&cinfo, buffer, buffer_size); 1.351 + cinfo.image_width = width; 1.352 + cinfo.image_height = height; 1.353 + cinfo.input_components = dimbuf; 1.354 + cinfo.in_color_space = colortype; 1.355 + jpeg_set_defaults(&cinfo); 1.356 + jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE); 1.357 + jpeg_start_compress(&cinfo,TRUE); 1.358 + 1.359 + const unsigned int row_stride = width*dimbuf; 1.360 + JSAMPROW row_pointer[1]; 1.361 + while (cinfo.next_scanline < cinfo.image_height) { 1.362 + row_pointer[0] = &buf[cinfo.next_scanline*row_stride]; 1.363 + jpeg_write_scanlines(&cinfo,row_pointer,1); 1.364 + } 1.365 + jpeg_finish_compress(&cinfo); 1.366 + delete[] buf; 1.367 + jpeg_destroy_compress(&cinfo); 1.368 + buffer_size = jpeg_mem_size(&cinfo); 1.369 + return *this; 1.370 +}