/src/FreeImage/Source/FreeImage/ConversionType.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 689 lines · 558 code · 60 blank · 71 comment · 49 complexity · 37ae57f05b425f4652e87bbfb4e35b38 MD5 · raw file

  1. // ==========================================================
  2. // Bitmap conversion routines
  3. //
  4. // Design and implementation by
  5. // - Hervé Drolon (drolon@infonie.fr)
  6. //
  7. // This file is part of FreeImage 3
  8. //
  9. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  10. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  11. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  12. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  13. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  14. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  15. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  16. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  17. // THIS DISCLAIMER.
  18. //
  19. // Use at your own risk!
  20. // ==========================================================
  21. #include "FreeImage.h"
  22. #include "Utilities.h"
  23. // ----------------------------------------------------------
  24. /** Convert a greyscale image of type Tsrc to type Tdst.
  25. Conversion is done using standard C language casting convention.
  26. */
  27. template<class Tdst, class Tsrc>
  28. class CONVERT_TYPE
  29. {
  30. public:
  31. FIBITMAP* convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type);
  32. };
  33. template<class Tdst, class Tsrc> FIBITMAP*
  34. CONVERT_TYPE<Tdst, Tsrc>::convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type) {
  35. FIBITMAP *dst = NULL;
  36. unsigned width = FreeImage_GetWidth(src);
  37. unsigned height = FreeImage_GetHeight(src);
  38. unsigned bpp = FreeImage_GetBPP(src);
  39. // allocate dst image
  40. dst = FreeImage_AllocateT(dst_type, width, height, bpp,
  41. FreeImage_GetRedMask(src), FreeImage_GetGreenMask(src), FreeImage_GetBlueMask(src));
  42. if(!dst) return NULL;
  43. // convert from src_type to dst_type
  44. for(unsigned y = 0; y < height; y++) {
  45. const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
  46. Tdst *dst_bits = reinterpret_cast<Tdst*>(FreeImage_GetScanLine(dst, y));
  47. for(unsigned x = 0; x < width; x++) {
  48. *dst_bits++ = static_cast<Tdst>(*src_bits++);
  49. }
  50. }
  51. return dst;
  52. }
  53. /** Convert a greyscale image of type Tsrc to a 8-bit grayscale dib.
  54. Conversion is done using either a linear scaling from [min, max] to [0, 255]
  55. or a rounding from src_pixel to (BYTE) MIN(255, MAX(0, q)) where int q = int(src_pixel + 0.5);
  56. */
  57. template<class Tsrc>
  58. class CONVERT_TO_BYTE
  59. {
  60. public:
  61. FIBITMAP* convert(FIBITMAP *src, BOOL scale_linear);
  62. };
  63. template<class Tsrc> FIBITMAP*
  64. CONVERT_TO_BYTE<Tsrc>::convert(FIBITMAP *src, BOOL scale_linear) {
  65. FIBITMAP *dst = NULL;
  66. unsigned x, y;
  67. unsigned width = FreeImage_GetWidth(src);
  68. unsigned height = FreeImage_GetHeight(src);
  69. // allocate a 8-bit dib
  70. dst = FreeImage_AllocateT(FIT_BITMAP, width, height, 8, 0, 0, 0);
  71. if(!dst) return NULL;
  72. // build a greyscale palette
  73. RGBQUAD *pal = FreeImage_GetPalette(dst);
  74. for(int i = 0; i < 256; i++) {
  75. pal[i].rgbRed = (BYTE)i;
  76. pal[i].rgbGreen = (BYTE)i;
  77. pal[i].rgbBlue = (BYTE)i;
  78. }
  79. // convert the src image to dst
  80. // (FIBITMAP are stored upside down)
  81. if(scale_linear) {
  82. Tsrc max, min;
  83. double scale;
  84. // find the min and max value of the image
  85. Tsrc l_min, l_max;
  86. min = 255, max = 0;
  87. for(y = 0; y < height; y++) {
  88. Tsrc *bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
  89. MAXMIN(bits, width, l_max, l_min);
  90. if(l_max > max) max = l_max;
  91. if(l_min < min) min = l_min;
  92. }
  93. if(max == min) {
  94. max = 255; min = 0;
  95. }
  96. // compute the scaling factor
  97. scale = 255 / (double)(max - min);
  98. // scale to 8-bit
  99. for(y = 0; y < height; y++) {
  100. Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
  101. BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
  102. for(x = 0; x < width; x++) {
  103. dst_bits[x] = (BYTE)( scale * (src_bits[x] - min) + 0.5);
  104. }
  105. }
  106. } else {
  107. for(y = 0; y < height; y++) {
  108. Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
  109. BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
  110. for(x = 0; x < width; x++) {
  111. // rounding
  112. int q = int(src_bits[x] + 0.5);
  113. dst_bits[x] = (BYTE) MIN(255, MAX(0, q));
  114. }
  115. }
  116. }
  117. return dst;
  118. }
  119. /** Convert a greyscale image of type Tsrc to a FICOMPLEX dib.
  120. */
  121. template<class Tsrc>
  122. class CONVERT_TO_COMPLEX
  123. {
  124. public:
  125. FIBITMAP* convert(FIBITMAP *src);
  126. };
  127. template<class Tsrc> FIBITMAP*
  128. CONVERT_TO_COMPLEX<Tsrc>::convert(FIBITMAP *src) {
  129. FIBITMAP *dst = NULL;
  130. unsigned width = FreeImage_GetWidth(src);
  131. unsigned height = FreeImage_GetHeight(src);
  132. // allocate dst image
  133. dst = FreeImage_AllocateT(FIT_COMPLEX, width, height);
  134. if(!dst) return NULL;
  135. // convert from src_type to FIT_COMPLEX
  136. for(unsigned y = 0; y < height; y++) {
  137. const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
  138. FICOMPLEX *dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
  139. for(unsigned x = 0; x < width; x++) {
  140. dst_bits[x].r = (double)src_bits[x];
  141. dst_bits[x].i = 0;
  142. }
  143. }
  144. return dst;
  145. }
  146. // ----------------------------------------------------------
  147. // Convert from type BYTE to type X
  148. CONVERT_TYPE<unsigned short, BYTE> convertByteToUShort;
  149. CONVERT_TYPE<short, BYTE> convertByteToShort;
  150. CONVERT_TYPE<DWORD, BYTE> convertByteToULong;
  151. CONVERT_TYPE<LONG, BYTE> convertByteToLong;
  152. CONVERT_TYPE<float, BYTE> convertByteToFloat;
  153. CONVERT_TYPE<double, BYTE> convertByteToDouble;
  154. // Convert from type X to type BYTE
  155. CONVERT_TO_BYTE<unsigned short> convertUShortToByte;
  156. CONVERT_TO_BYTE<short> convertShortToByte;
  157. CONVERT_TO_BYTE<DWORD> convertULongToByte;
  158. CONVERT_TO_BYTE<LONG> convertLongToByte;
  159. CONVERT_TO_BYTE<float> convertFloatToByte;
  160. CONVERT_TO_BYTE<double> convertDoubleToByte;
  161. // Convert from type X to type float
  162. CONVERT_TYPE<float, unsigned short> convertUShortToFloat;
  163. CONVERT_TYPE<float, short> convertShortToFloat;
  164. CONVERT_TYPE<float, DWORD> convertULongToFloat;
  165. CONVERT_TYPE<float, LONG> convertLongToFloat;
  166. // Convert from type X to type double
  167. CONVERT_TYPE<double, unsigned short> convertUShortToDouble;
  168. CONVERT_TYPE<double, short> convertShortToDouble;
  169. CONVERT_TYPE<double, DWORD> convertULongToDouble;
  170. CONVERT_TYPE<double, LONG> convertLongToDouble;
  171. CONVERT_TYPE<double, float> convertFloatToDouble;
  172. // Convert from type X to type FICOMPLEX
  173. CONVERT_TO_COMPLEX<BYTE> convertByteToComplex;
  174. CONVERT_TO_COMPLEX<unsigned short> convertUShortToComplex;
  175. CONVERT_TO_COMPLEX<short> convertShortToComplex;
  176. CONVERT_TO_COMPLEX<DWORD> convertULongToComplex;
  177. CONVERT_TO_COMPLEX<LONG> convertLongToComplex;
  178. CONVERT_TO_COMPLEX<float> convertFloatToComplex;
  179. CONVERT_TO_COMPLEX<double> convertDoubleToComplex;
  180. // ----------------------------------------------------------
  181. // ----------------------------------------------------------
  182. // smart convert X to standard FIBITMAP
  183. // ----------------------------------------------------------
  184. /** Convert image of any type to a standard 8-bit greyscale image.
  185. For standard images, a clone of the input image is returned.
  186. When the scale_linear parameter is TRUE, conversion is done by scaling linearly
  187. each pixel to an integer value between [0..255]. When it is FALSE, conversion is done
  188. by rounding each float pixel to an integer between [0..255].
  189. For complex images, the magnitude is extracted as a double image, then converted according to the scale parameter.
  190. @param image Image to convert
  191. @param scale_linear Linear scaling / rounding switch
  192. */
  193. FIBITMAP* DLL_CALLCONV
  194. FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear) {
  195. FIBITMAP *dst = NULL;
  196. if(!src) return NULL;
  197. // convert from src_type to FIT_BITMAP
  198. const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
  199. switch(src_type) {
  200. case FIT_BITMAP: // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
  201. dst = FreeImage_Clone(src);
  202. break;
  203. case FIT_UINT16: // array of unsigned short: unsigned 16-bit
  204. dst = convertUShortToByte.convert(src, scale_linear);
  205. break;
  206. case FIT_INT16: // array of short: signed 16-bit
  207. dst = convertShortToByte.convert(src, scale_linear);
  208. break;
  209. case FIT_UINT32: // array of unsigned long: unsigned 32-bit
  210. dst = convertULongToByte.convert(src, scale_linear);
  211. break;
  212. case FIT_INT32: // array of long: signed 32-bit
  213. dst = convertLongToByte.convert(src, scale_linear);
  214. break;
  215. case FIT_FLOAT: // array of float: 32-bit
  216. dst = convertFloatToByte.convert(src, scale_linear);
  217. break;
  218. case FIT_DOUBLE: // array of double: 64-bit
  219. dst = convertDoubleToByte.convert(src, scale_linear);
  220. break;
  221. case FIT_COMPLEX: // array of FICOMPLEX: 2 x 64-bit
  222. {
  223. // Convert to type FIT_DOUBLE
  224. FIBITMAP *dib_double = FreeImage_GetComplexChannel(src, FICC_MAG);
  225. if(dib_double) {
  226. // Convert to a standard bitmap (linear scaling)
  227. dst = convertDoubleToByte.convert(dib_double, scale_linear);
  228. // Free image of type FIT_DOUBLE
  229. FreeImage_Unload(dib_double);
  230. }
  231. }
  232. break;
  233. case FIT_RGB16: // 48-bit RGB image: 3 x 16-bit
  234. break;
  235. case FIT_RGBA16: // 64-bit RGBA image: 4 x 16-bit
  236. break;
  237. case FIT_RGBF: // 96-bit RGB float image: 3 x 32-bit IEEE floating point
  238. break;
  239. case FIT_RGBAF: // 128-bit RGBA float image: 4 x 32-bit IEEE floating point
  240. break;
  241. }
  242. if(NULL == dst) {
  243. FreeImage_OutputMessageProc(FIF_UNKNOWN, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, FIT_BITMAP);
  244. } else {
  245. // copy metadata from src to dst
  246. FreeImage_CloneMetadata(dst, src);
  247. }
  248. return dst;
  249. }
  250. // ----------------------------------------------------------
  251. // smart convert X to Y
  252. // ----------------------------------------------------------
  253. FIBITMAP* DLL_CALLCONV
  254. FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear) {
  255. FIBITMAP *dst = NULL;
  256. if(!FreeImage_HasPixels(src)) return NULL;
  257. // convert from src_type to dst_type
  258. const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
  259. if(src_type == dst_type) {
  260. return FreeImage_Clone(src);
  261. }
  262. const unsigned src_bpp = FreeImage_GetBPP(src);
  263. switch(src_type) {
  264. case FIT_BITMAP:
  265. switch(dst_type) {
  266. case FIT_UINT16:
  267. dst = FreeImage_ConvertToUINT16(src);
  268. break;
  269. case FIT_INT16:
  270. dst = (src_bpp == 8) ? convertByteToShort.convert(src, dst_type) : NULL;
  271. break;
  272. case FIT_UINT32:
  273. dst = (src_bpp == 8) ? convertByteToULong.convert(src, dst_type) : NULL;
  274. break;
  275. case FIT_INT32:
  276. dst = (src_bpp == 8) ? convertByteToLong.convert(src, dst_type) : NULL;
  277. break;
  278. case FIT_FLOAT:
  279. dst = FreeImage_ConvertToFloat(src);
  280. break;
  281. case FIT_DOUBLE:
  282. dst = (src_bpp == 8) ? convertByteToDouble.convert(src, dst_type) : NULL;
  283. break;
  284. case FIT_COMPLEX:
  285. dst = (src_bpp == 8) ? convertByteToComplex.convert(src) : NULL;
  286. break;
  287. case FIT_RGB16:
  288. dst = FreeImage_ConvertToRGB16(src);
  289. break;
  290. case FIT_RGBA16:
  291. break;
  292. case FIT_RGBF:
  293. dst = FreeImage_ConvertToRGBF(src);
  294. break;
  295. case FIT_RGBAF:
  296. break;
  297. }
  298. break;
  299. case FIT_UINT16:
  300. switch(dst_type) {
  301. case FIT_BITMAP:
  302. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  303. break;
  304. case FIT_INT16:
  305. break;
  306. case FIT_UINT32:
  307. break;
  308. case FIT_INT32:
  309. break;
  310. case FIT_FLOAT:
  311. dst = FreeImage_ConvertToFloat(src);
  312. break;
  313. case FIT_DOUBLE:
  314. dst = convertUShortToDouble.convert(src, dst_type);
  315. break;
  316. case FIT_COMPLEX:
  317. dst = convertUShortToComplex.convert(src);
  318. break;
  319. case FIT_RGB16:
  320. dst = FreeImage_ConvertToRGB16(src);
  321. break;
  322. case FIT_RGBA16:
  323. break;
  324. case FIT_RGBF:
  325. dst = FreeImage_ConvertToRGBF(src);
  326. break;
  327. case FIT_RGBAF:
  328. break;
  329. }
  330. break;
  331. case FIT_INT16:
  332. switch(dst_type) {
  333. case FIT_BITMAP:
  334. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  335. break;
  336. case FIT_UINT16:
  337. break;
  338. case FIT_UINT32:
  339. break;
  340. case FIT_INT32:
  341. break;
  342. case FIT_FLOAT:
  343. dst = convertShortToFloat.convert(src, dst_type);
  344. break;
  345. case FIT_DOUBLE:
  346. dst = convertShortToDouble.convert(src, dst_type);
  347. break;
  348. case FIT_COMPLEX:
  349. dst = convertShortToComplex.convert(src);
  350. break;
  351. case FIT_RGB16:
  352. break;
  353. case FIT_RGBA16:
  354. break;
  355. case FIT_RGBF:
  356. break;
  357. case FIT_RGBAF:
  358. break;
  359. }
  360. break;
  361. case FIT_UINT32:
  362. switch(dst_type) {
  363. case FIT_BITMAP:
  364. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  365. break;
  366. case FIT_UINT16:
  367. break;
  368. case FIT_INT16:
  369. break;
  370. case FIT_INT32:
  371. break;
  372. case FIT_FLOAT:
  373. dst = convertULongToFloat.convert(src, dst_type);
  374. break;
  375. case FIT_DOUBLE:
  376. dst = convertULongToDouble.convert(src, dst_type);
  377. break;
  378. case FIT_COMPLEX:
  379. dst = convertULongToComplex.convert(src);
  380. break;
  381. case FIT_RGB16:
  382. break;
  383. case FIT_RGBA16:
  384. break;
  385. case FIT_RGBF:
  386. break;
  387. case FIT_RGBAF:
  388. break;
  389. }
  390. break;
  391. case FIT_INT32:
  392. switch(dst_type) {
  393. case FIT_BITMAP:
  394. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  395. break;
  396. case FIT_UINT16:
  397. break;
  398. case FIT_INT16:
  399. break;
  400. case FIT_UINT32:
  401. break;
  402. case FIT_FLOAT:
  403. dst = convertLongToFloat.convert(src, dst_type);
  404. break;
  405. case FIT_DOUBLE:
  406. dst = convertLongToDouble.convert(src, dst_type);
  407. break;
  408. case FIT_COMPLEX:
  409. dst = convertLongToComplex.convert(src);
  410. break;
  411. case FIT_RGB16:
  412. break;
  413. case FIT_RGBA16:
  414. break;
  415. case FIT_RGBF:
  416. break;
  417. case FIT_RGBAF:
  418. break;
  419. }
  420. break;
  421. case FIT_FLOAT:
  422. switch(dst_type) {
  423. case FIT_BITMAP:
  424. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  425. break;
  426. case FIT_UINT16:
  427. break;
  428. case FIT_INT16:
  429. break;
  430. case FIT_UINT32:
  431. break;
  432. case FIT_INT32:
  433. break;
  434. case FIT_DOUBLE:
  435. dst = convertFloatToDouble.convert(src, dst_type);
  436. break;
  437. case FIT_COMPLEX:
  438. dst = convertFloatToComplex.convert(src);
  439. break;
  440. case FIT_RGB16:
  441. break;
  442. case FIT_RGBA16:
  443. break;
  444. case FIT_RGBF:
  445. dst = FreeImage_ConvertToRGBF(src);
  446. break;
  447. case FIT_RGBAF:
  448. break;
  449. }
  450. break;
  451. case FIT_DOUBLE:
  452. switch(dst_type) {
  453. case FIT_BITMAP:
  454. dst = FreeImage_ConvertToStandardType(src, scale_linear);
  455. break;
  456. case FIT_UINT16:
  457. break;
  458. case FIT_INT16:
  459. break;
  460. case FIT_UINT32:
  461. break;
  462. case FIT_INT32:
  463. break;
  464. case FIT_FLOAT:
  465. break;
  466. case FIT_COMPLEX:
  467. dst = convertDoubleToComplex.convert(src);
  468. break;
  469. case FIT_RGB16:
  470. break;
  471. case FIT_RGBA16:
  472. break;
  473. case FIT_RGBF:
  474. break;
  475. case FIT_RGBAF:
  476. break;
  477. }
  478. break;
  479. case FIT_COMPLEX:
  480. switch(dst_type) {
  481. case FIT_BITMAP:
  482. break;
  483. case FIT_UINT16:
  484. break;
  485. case FIT_INT16:
  486. break;
  487. case FIT_UINT32:
  488. break;
  489. case FIT_INT32:
  490. break;
  491. case FIT_FLOAT:
  492. break;
  493. case FIT_DOUBLE:
  494. break;
  495. case FIT_RGB16:
  496. break;
  497. case FIT_RGBA16:
  498. break;
  499. case FIT_RGBF:
  500. break;
  501. case FIT_RGBAF:
  502. break;
  503. }
  504. break;
  505. case FIT_RGB16:
  506. switch(dst_type) {
  507. case FIT_BITMAP:
  508. dst = FreeImage_ConvertTo24Bits(src);
  509. break;
  510. case FIT_UINT16:
  511. dst = FreeImage_ConvertToUINT16(src);
  512. break;
  513. case FIT_INT16:
  514. break;
  515. case FIT_UINT32:
  516. break;
  517. case FIT_INT32:
  518. break;
  519. case FIT_FLOAT:
  520. dst = FreeImage_ConvertToFloat(src);
  521. break;
  522. case FIT_DOUBLE:
  523. break;
  524. case FIT_COMPLEX:
  525. break;
  526. case FIT_RGBA16:
  527. break;
  528. case FIT_RGBF:
  529. dst = FreeImage_ConvertToRGBF(src);
  530. break;
  531. case FIT_RGBAF:
  532. break;
  533. }
  534. break;
  535. case FIT_RGBA16:
  536. switch(dst_type) {
  537. case FIT_BITMAP:
  538. dst = FreeImage_ConvertTo32Bits(src);
  539. break;
  540. case FIT_UINT16:
  541. dst = FreeImage_ConvertToUINT16(src);
  542. break;
  543. case FIT_INT16:
  544. break;
  545. case FIT_UINT32:
  546. break;
  547. case FIT_INT32:
  548. break;
  549. case FIT_FLOAT:
  550. dst = FreeImage_ConvertToFloat(src);
  551. break;
  552. case FIT_DOUBLE:
  553. break;
  554. case FIT_COMPLEX:
  555. break;
  556. case FIT_RGB16:
  557. dst = FreeImage_ConvertToRGB16(src);
  558. break;
  559. case FIT_RGBF:
  560. dst = FreeImage_ConvertToRGBF(src);
  561. break;
  562. case FIT_RGBAF:
  563. break;
  564. }
  565. break;
  566. case FIT_RGBF:
  567. switch(dst_type) {
  568. case FIT_BITMAP:
  569. break;
  570. case FIT_UINT16:
  571. break;
  572. case FIT_INT16:
  573. break;
  574. case FIT_UINT32:
  575. break;
  576. case FIT_INT32:
  577. break;
  578. case FIT_FLOAT:
  579. dst = FreeImage_ConvertToFloat(src);
  580. break;
  581. case FIT_DOUBLE:
  582. break;
  583. case FIT_COMPLEX:
  584. break;
  585. case FIT_RGB16:
  586. break;
  587. case FIT_RGBA16:
  588. break;
  589. case FIT_RGBAF:
  590. break;
  591. }
  592. break;
  593. case FIT_RGBAF:
  594. switch(dst_type) {
  595. case FIT_BITMAP:
  596. break;
  597. case FIT_UINT16:
  598. break;
  599. case FIT_INT16:
  600. break;
  601. case FIT_UINT32:
  602. break;
  603. case FIT_INT32:
  604. break;
  605. case FIT_FLOAT:
  606. dst = FreeImage_ConvertToFloat(src);
  607. break;
  608. case FIT_DOUBLE:
  609. break;
  610. case FIT_COMPLEX:
  611. break;
  612. case FIT_RGB16:
  613. break;
  614. case FIT_RGBA16:
  615. break;
  616. case FIT_RGBF:
  617. dst = FreeImage_ConvertToRGBF(src);
  618. break;
  619. }
  620. break;
  621. }
  622. if(NULL == dst) {
  623. FreeImage_OutputMessageProc(FIF_UNKNOWN, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, dst_type);
  624. } else {
  625. // copy metadata from src to dst
  626. FreeImage_CloneMetadata(dst, src);
  627. }
  628. return dst;
  629. }