/interface{}/src/opencv-master/opencv110/highgui/src/loadsave_new.cpp

https://github.com/Golangltd/codeclass · C++ · 375 lines · 294 code · 73 blank · 8 comment · 105 complexity · 29436fdd4798fb2aec546a4e3d84a596 MD5 · raw file

  1. // Copyright 2014 <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. #include "_highgui.h"
  5. #include "jpge.h"
  6. #include "jpgd.h"
  7. #include "lodepng.h"
  8. #include "EasyBMP.h"
  9. #include <string>
  10. // ----------------------------------------------------------------------------
  11. static std::string icvLowerString(const std::string& str) {
  12. std::string s = str;
  13. for(std::string::iterator i = s.begin(); i != s.end(); ++i) {
  14. if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
  15. }
  16. return s;
  17. }
  18. static bool icvHasPrefixString(const std::string& str, const std::string& prefix)
  19. {
  20. return str.size() >= prefix.size() &&
  21. str.compare(0, prefix.size(), prefix) == 0;
  22. }
  23. static bool icvHasSuffixString(const std::string& str, const std::string& suffix)
  24. {
  25. return str.size() >= suffix.size() &&
  26. str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
  27. }
  28. static bool icvLoadFileData(const char* name, std::string* data) {
  29. FILE* fp = fopen(name, "rb");
  30. if(!fp) return false;
  31. fseek(fp, 0, SEEK_END);
  32. data->resize(ftell(fp));
  33. rewind(fp);
  34. int n = fread((void*)data->data(), 1, data->size(), fp);
  35. fclose(fp);
  36. return (n == data->size());
  37. }
  38. static bool icvSaveFileData(const char* name, const char* data, int size) {
  39. FILE* fp = fopen(name, "wb");
  40. if(!fp) return false;
  41. int n = fwrite((void*)data, 1, size, fp);
  42. fclose(fp);
  43. return (n == size);
  44. }
  45. // ----------------------------------------------------------------------------
  46. static IplImage* icvDecodeJpg(const std::string& data, int iscolor)
  47. {
  48. int channels = iscolor? 3: 1;
  49. int width, height, actual_comps;
  50. unsigned char * d = jpgd::decompress_jpeg_image_from_memory(
  51. (const unsigned char*)data.data(), data.size(),
  52. &width, &height, &actual_comps, channels
  53. );
  54. if(d == NULL) {
  55. return NULL;
  56. }
  57. IplImage* m = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, channels);
  58. memcpy(m->imageData, d, width*height*channels);
  59. m->widthStep = width*channels;
  60. free(d);
  61. cvConvertImage(m, m, CV_CVTIMG_SWAP_RB);
  62. return m;
  63. }
  64. static bool icvEncodeJpg(
  65. std::string* dst, const char* data, int size,
  66. int width, int height, int channels, int quality /* =90 */,
  67. int width_step /* =0 */
  68. ) {
  69. if(dst == NULL || data == NULL || size <= 0) {
  70. return false;
  71. }
  72. if(width <= 0 || height <= 0) {
  73. return false;
  74. }
  75. if(channels != 1 && channels != 3) {
  76. return false;
  77. }
  78. if(quality <= 0 || quality > 100) {
  79. return false;
  80. }
  81. if(width_step < width*channels) {
  82. width_step = width*channels;
  83. }
  84. std::string tmp;
  85. const char* pSrcData = data;
  86. jpge::params comp_params;
  87. if(channels == 3) {
  88. comp_params.m_subsampling = jpge::H2V2; // RGB
  89. comp_params.m_quality = quality;
  90. if(width_step > width*channels) {
  91. tmp.resize(width*height*3);
  92. for(int i = 0; i < height; ++i) {
  93. char* ppTmp = (char*)tmp.data() + i*width*channels;
  94. char* ppSrc = (char*)data + i*width_step;
  95. memcpy(ppTmp, ppSrc, width*channels);
  96. }
  97. pSrcData = tmp.data();
  98. }
  99. } else {
  100. comp_params.m_subsampling = jpge::Y_ONLY; // Gray
  101. comp_params.m_quality = quality;
  102. tmp.resize(width*height*3);
  103. for(int i = 0; i < height; ++i) {
  104. char* ppTmp = (char*)tmp.data() + i*width*3;
  105. char* ppSrc = (char*)data + i*width_step;
  106. for(int j = 0; j < width; ++j) {
  107. ppTmp[j*3+0] = ppSrc[j];
  108. ppTmp[j*3+1] = ppSrc[j];
  109. ppTmp[j*3+2] = ppSrc[j];
  110. }
  111. }
  112. channels = 3;
  113. pSrcData = tmp.data();
  114. }
  115. int buf_size = ((width*height*3)>1024)? (width*height*3): 1024;
  116. dst->resize(buf_size);
  117. bool rv = compress_image_to_jpeg_file_in_memory(
  118. (void*)dst->data(), buf_size, width, height, channels,
  119. (const jpge::uint8*)pSrcData,
  120. comp_params
  121. );
  122. if(!rv) {
  123. dst->clear();
  124. return false;
  125. }
  126. dst->resize(buf_size);
  127. return true;
  128. }
  129. // ----------------------------------------------------------------------------
  130. static bool icvDecodePng32(std::string* dst, const char* data, int size, int* width, int* height) {
  131. if(dst == NULL || data == NULL || size <= 0) {
  132. return false;
  133. }
  134. if(width == NULL || height == NULL) {
  135. return false;
  136. }
  137. unsigned char* img;
  138. unsigned w, h;
  139. unsigned err = lodepng_decode32(&img, &w, &h, (const unsigned char*)data, size);
  140. if(err != 0) return false;
  141. dst->assign((const char*)img, w*h*4);
  142. free(img);
  143. *width = w;
  144. *height = h;
  145. return true;
  146. }
  147. static bool icvDecodePng24(std::string* dst, const char* data, int size, int* width, int* height) {
  148. if(dst == NULL || data == NULL || size <= 0) {
  149. return false;
  150. }
  151. if(width == NULL || height == NULL) {
  152. return false;
  153. }
  154. unsigned char* img;
  155. unsigned w, h;
  156. unsigned err = lodepng_decode32(&img, &w, &h, (const unsigned char*)data, size);
  157. if(err != 0) return false;
  158. dst->assign((const char*)img, w*h*3);
  159. free(img);
  160. *width = w;
  161. *height = h;
  162. return true;
  163. }
  164. static bool icvEncodePng32(std::string* dst, const char* data, int size, int width, int height, int width_step/*=0*/) {
  165. if(dst == NULL || data == NULL || size <= 0) {
  166. return false;
  167. }
  168. if(width <= 0 || height <= 0) {
  169. return false;
  170. }
  171. if(width_step < width*4) {
  172. width_step = width*4;
  173. }
  174. std::string tmp;
  175. const char* pSrcData = data;
  176. if(width_step > width*4) {
  177. tmp.resize(width*height*4);
  178. for(int i = 0; i < height; ++i) {
  179. char* ppTmp = (char*)tmp.data() + i*width*4;
  180. char* ppSrc = (char*)data + i*width_step;
  181. memcpy(ppTmp, ppSrc, width*4);
  182. }
  183. pSrcData = tmp.data();
  184. }
  185. unsigned char* png;
  186. size_t pngsize;
  187. unsigned err = lodepng_encode32(&png, &pngsize, (const unsigned char*)pSrcData, width, height);
  188. if(err != 0) return false;
  189. dst->assign((const char*)png, pngsize);
  190. free(png);
  191. return true;
  192. }
  193. static bool icvEncodePng24(std::string* dst, const char* data, int size, int width, int height, int width_step/*=0*/) {
  194. if(dst == NULL || data == NULL || size <= 0) {
  195. return false;
  196. }
  197. if(width <= 0 || height <= 0) {
  198. return false;
  199. }
  200. if(width_step < width*3) {
  201. width_step = width*3;
  202. }
  203. std::string tmp;
  204. const char* pSrcData = data;
  205. if(width_step > width*3) {
  206. tmp.resize(width*height*3);
  207. for(int i = 0; i < height; ++i) {
  208. char* ppTmp = (char*)tmp.data() + i*width*3;
  209. char* ppSrc = (char*)data + i*width_step;
  210. memcpy(ppTmp, ppSrc, width*3);
  211. }
  212. pSrcData = tmp.data();
  213. }
  214. unsigned char* png;
  215. size_t pngsize;
  216. unsigned err = lodepng_encode24(&png, &pngsize, (const unsigned char*)pSrcData, width, height);
  217. if(err != 0) return false;
  218. dst->assign((const char*)png, pngsize);
  219. free(png);
  220. return true;
  221. }
  222. // ----------------------------------------------------------------------------
  223. CV_IMPL
  224. int cvHaveImageReader( const char* filename )
  225. {
  226. std::string name = icvLowerString(filename);
  227. if(icvHasSuffixString(name, ".jpg")) return 1;
  228. if(icvHasSuffixString(name, ".jpeg")) return 1;
  229. if(icvHasSuffixString(name, ".png")) return 1;
  230. if(icvHasSuffixString(name, ".bmp")) return 0; // todo
  231. return 0;
  232. }
  233. CV_IMPL
  234. int cvHaveImageWriter( const char* filename )
  235. {
  236. std::string name = icvLowerString(filename);
  237. if(icvHasSuffixString(name, ".jpg")) return 1;
  238. if(icvHasSuffixString(name, ".jpeg")) return 1;
  239. if(icvHasSuffixString(name, ".png")) return 1;
  240. if(icvHasSuffixString(name, ".bmp")) return 0; // todo
  241. return 0;
  242. }
  243. CV_IMPL
  244. IplImage* cvLoadImage( const char* filename, int iscolor )
  245. {
  246. if(!filename || !filename[0]) {
  247. return NULL;
  248. }
  249. std::string data;
  250. if(!icvLoadFileData(filename, &data)) {
  251. return NULL;
  252. }
  253. std::string lowerName = icvLowerString(filename);
  254. if(icvHasSuffixString(lowerName, ".jpg")) {
  255. return icvDecodeJpg(data, iscolor);
  256. }
  257. if(icvHasSuffixString(lowerName, ".jpeg")) {
  258. return icvDecodeJpg(data, iscolor);
  259. }
  260. return NULL;
  261. }
  262. CV_IMPL
  263. CvMat* cvLoadImageM( const char* filename, int iscolor )
  264. {
  265. if(!filename || !filename[0]) {
  266. return NULL;
  267. }
  268. return NULL;//cvLoadImageM_goproxy(filename, iscolor);
  269. }
  270. CV_IMPL
  271. int cvSaveImage( const char* filename, const CvArr* arr )
  272. {
  273. if(!filename || !filename[0] || !arr) {
  274. return 0;
  275. }
  276. if(!CV_IS_IMAGE(arr)) {
  277. return 0;
  278. }
  279. IplImage* img = (IplImage*)arr;
  280. std::string data;
  281. if(img->depth != IPL_DEPTH_8U) {
  282. return 0;
  283. }
  284. std::string lowerName = icvLowerString(filename);
  285. if(icvHasSuffixString(lowerName, ".jpg") || icvHasSuffixString(lowerName, ".jpeg")) {
  286. cvConvertImage(img, img, CV_CVTIMG_SWAP_RB);
  287. if(!icvEncodeJpg(&data,
  288. img->imageData, img->imageSize,
  289. img->width, img->height, img->nChannels,
  290. 90, img->widthStep
  291. )) {
  292. cvConvertImage(img, img, CV_CVTIMG_SWAP_RB);
  293. return 0;
  294. }
  295. cvConvertImage(img, img, CV_CVTIMG_SWAP_RB);
  296. }
  297. if(!icvSaveFileData(filename, data.data(), data.size())) {
  298. return 0;
  299. }
  300. return 1;
  301. }
  302. // ----------------------------------------------------------------------------