github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/test/test_util_jpg.cc (about)

     1  // Copyright 2013 <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "test_util.h"
     6  
     7  #include "./jpeg/jpge.cpp"
     8  #include "./jpeg/jpgd.cpp"
     9  
    10  #include <string>
    11  
    12  bool jpegDecode(std::string* dst, const char* data, int size, int* width, int* height, int* channels) {
    13  	if(dst == NULL || data == NULL || size <= 0) {
    14  		return false;
    15  	}
    16  	if(width == NULL || height == NULL || channels == NULL) {
    17  		return false;
    18  	}
    19  
    20  	auto p = jpgd::decompress_jpeg_image_from_memory(
    21  		(const unsigned char *)data, size,
    22  		width, height, channels,
    23  		3
    24  	);
    25  	if(p == NULL) {
    26  		return false;
    27  	}
    28  	if(*width <= 0 || *height <= 0 || (*channels != 1 && *channels != 3)) {
    29  		free(p);
    30  		return false;
    31  	}
    32  
    33  	// if Gray: convert to RGB;
    34  	if(*channels == 1) {
    35  		dst->resize((*width)*(*height));
    36  		auto pDst = (unsigned char*)dst->data();
    37  		for(int i = 0; i < (*width)*(*height); ++i) {
    38  			pDst[i] = p[i*3];
    39  		}
    40  	} else {
    41  		dst->assign((const char*)p, (*width)*(*height)*(*channels));
    42  	}
    43  	free(p);
    44  
    45  	return true;
    46  }
    47  
    48  bool jpegEncode(
    49  	std::string* dst, const char* data, int size,
    50  	int width, int height, int channels, int quality /* =90 */,
    51  	int width_step /* =0 */
    52  ) {
    53  	if(dst == NULL || data == NULL || size <= 0) {
    54  		return false;
    55  	}
    56  	if(width <= 0 || height <= 0) {
    57  		return false;
    58  	}
    59  	if(channels != 1 && channels != 3) {
    60  		return false;
    61  	}
    62  	if(quality <= 0 || quality > 100) {
    63  		return false;
    64  	}
    65  
    66  	if(width_step < width*channels) {
    67  		width_step = width*channels;
    68  	}
    69  
    70  	std::string tmp;
    71  	auto pSrcData = data;
    72  
    73  	jpge::params comp_params;
    74  	if(channels == 3) {
    75  		comp_params.m_subsampling = jpge::H2V2;   // RGB
    76  		comp_params.m_quality = quality;
    77  
    78  		if(width_step > width*channels) {
    79  			tmp.resize(width*height*3);
    80  			for(int i = 0; i < height; ++i) {
    81  				auto ppTmp = (char*)tmp.data() + i*width*channels;
    82  				auto ppSrc = (char*)data + i*width_step;
    83  				memcpy(ppTmp, ppSrc, width*channels);
    84  			}
    85  			pSrcData = tmp.data();
    86  		}
    87  	} else {
    88  		comp_params.m_subsampling = jpge::Y_ONLY; // Gray
    89  		comp_params.m_quality = quality;
    90  
    91  		// if Gray: convert to RGB;
    92  		tmp.resize(width*height*3);
    93  		for(int i = 0; i < height; ++i) {
    94  			auto ppTmp = (char*)tmp.data() + i*width*3;
    95  			auto ppSrc = (char*)data + i*width_step;
    96  			for(int j = 0; j < width; ++j) {
    97  				ppTmp[i*3+0] = ppSrc[i];
    98  				ppTmp[i*3+1] = ppSrc[i];
    99  				ppTmp[i*3+2] = ppSrc[i];
   100  			}
   101  		}
   102  		channels = 3;
   103  		pSrcData = tmp.data();
   104  	}
   105  
   106  	int buf_size = ((width*height*3)>1024)? (width*height*3): 1024;
   107  	dst->resize(buf_size);
   108  	bool rv = compress_image_to_jpeg_file_in_memory(
   109  		(void*)dst->data(), buf_size, width, height, channels,
   110  		(const jpge::uint8*)pSrcData,
   111  		comp_params
   112  	);
   113  	if(!rv) {
   114  		dst->clear();
   115  		return false;
   116  	}
   117  
   118  	dst->resize(buf_size);
   119  	return true;
   120  }
   121