分享

一组rgb转换函数,支持rgb565/rgb888/xrgb8888之间的数据转换

 昵称14797374 2014-08-26

mybmp.h

Cpp代码 
  1. /******************************************************************** 
  2.     created:    2012/04/07 
  3.     filename:   mybmp.h 
  4.     author:      
  5.      
  6.     purpose:     
  7. *********************************************************************/  
  8.   
  9. #ifndef _mybmp_h__  
  10. #define _mybmp_h__  
  11. //-------------------------------------------------------------------  
  12.   
  13. #ifdef __cplusplus  
  14. extern "C" {  
  15. #endif  
  16.   
  17. #define UpAlign4(n) (((n) + 3) & ~3)  
  18. #define UpAlign8(n) (((n) + 7) & ~7)  
  19.   
  20. //拷贝数据  
  21. void rgb_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh, int bpp);  
  22. void rbg565_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh);  
  23. void rbg888_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh);  
  24. void rbgx8888_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh);  
  25.   
  26. //行数据翻转  
  27. void line_reversal(void * pdata, int w, int h, int bpp);  
  28. void rgb565_line_reversal(void * p565, int w, int h);  
  29. void rgb888_line_reversal(void * p888, int w, int h);  
  30. void rgbx8888_line_reversal(void * p8888, int w, int h);  
  31.   
  32. //转换  
  33. typedef void * (* RGB_CONVERT_FUN)(const void * psrc, int w, int h);  
  34. void * rgb565_to_rgb888_buffer(const void * psrc, int w, int h);  
  35. void * rgb888_to_rgb565_buffer(const void * psrc, int w, int h);  
  36. void * rgb565_to_rgbx8888_buffer(const void * psrc, int w, int h);  
  37. void * rgbx8888_to_rgb565_buffer(const void * psrc, int w, int h);  
  38. void * rgb888_to_rgbx8888_buffer(const void * psrc, int w, int h);  
  39. void * rgbx8888_to_rgb888_buffer(const void * psrc, int w, int h);  
  40. RGB_CONVERT_FUN get_convert_func(int frombpp, int tobpp);  
  41.   
  42. #ifdef __cplusplus  
  43. };  
  44. #endif  
  45.   
  46. //-------------------------------------------------------------------  
  47. #endif // #ifndef _mybmp_h__  

rgb_convert.c

Cpp代码 
  1. /******************************************************************** 
  2.     created:    2012/05/19 
  3.     filename:   rgb_convert.c 
  4.     author:      
  5.      
  6.     purpose:     
  7. *********************************************************************/  
  8.   
  9. //-------------------------------------------------------------------  
  10. #include <stdlib.h>  
  11. #include <stdio.h>  
  12. #include <memory.h>  
  13. #include "mybmp.h"  
  14.   
  15. //-------------------------------------------------------------------  
  16. //拷贝  
  17. void rgb_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh, int bpp)  
  18. {  
  19.     int bytes = UpAlign8(bpp) >> 3; // bpp / 8  
  20.     int srclinesize = UpAlign4(sw * bytes);  
  21.     int dstlinesize = UpAlign4(dw * bytes);  
  22.     int copylinesize = srclinesize < dstlinesize ? srclinesize : dstlinesize;  
  23.     int copylines = sh < dh ? sh : dh;  
  24.       
  25.     const unsigned char * psrcline = (const unsigned char *)psrc;  
  26.     const unsigned char * pend = psrcline + copylines * srclinesize;  
  27.     unsigned char * pdstline = (unsigned char *)pdst;  
  28.       
  29.     while (psrcline < pend) {  
  30.         memcpy(pdstline, psrcline, copylinesize);  
  31.         psrcline += srclinesize;  
  32.         pdstline += dstlinesize;  
  33.     }  
  34. }  
  35.   
  36. void rbg565_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh)  
  37. {  
  38.     rgb_copy(psrc, pdst, sw, sh, dw, dh, 16);  
  39. }  
  40.   
  41. void rbg888_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh)  
  42. {  
  43.     rgb_copy(psrc, pdst, sw, sh, dw, dh, 24);  
  44. }  
  45.   
  46. void rbgx8888_copy(const void * psrc, void * pdst, int sw, int sh, int dw, int dh)  
  47. {  
  48.     rgb_copy(psrc, pdst, sw, sh, dw, dh, 32);  
  49. }  
  50.   
  51. //-------------------------------------------------------------------  
  52. //行数据翻转  
  53. void line_reversal(void * pdata, int w, int h, int bpp)  
  54. {  
  55.     int bytes     = UpAlign8(bpp) >> 3; // bpp / 8  
  56.     int linesize  = UpAlign4(w * bytes);//4的整数倍  
  57.     int copylines = h >> 1;  
  58.   
  59.     int i;  
  60.     unsigned char * pline = NULL;  
  61.     unsigned char * pline1 = NULL;  
  62.     unsigned char * linebuffer = NULL;  
  63.   
  64.     if (pdata && w > 0 && h > 1) {//至少两行才需要翻转  
  65.         linebuffer = (unsigned char *)malloc(linesize);  
  66.         if (linebuffer) {  
  67.             pline  = (unsigned char *)pdata;  
  68.             pline1 = (unsigned char *)pdata + linesize * (h - 1);  
  69.             for (i = 0; i < copylines; i++) {  
  70.                 memcpy(linebuffer, pline, linesize);  
  71.                 memcpy(pline, pline1, linesize);  
  72.                 memcpy(pline1, linebuffer, linesize);  
  73.                 pline  += linesize;  
  74.                 pline1 -= linesize;  
  75.             }  
  76.             free(linebuffer);  
  77.         }  
  78.     }  
  79. }  
  80.   
  81. void rgb565_line_reversal(void * p565, int w, int h)  
  82. {  
  83.     line_reversal(p565, w, h, 16);  
  84. }  
  85.   
  86. void rgb888_line_reversal(void * p888, int w, int h)  
  87. {  
  88.     line_reversal(p888, w, h, 24);  
  89. }  
  90.   
  91. void rgbx8888_line_reversal(void * p8888, int w, int h)  
  92. {  
  93.     line_reversal(p8888, w, h, 32);  
  94. }  
  95.   
  96. //-------------------------------------------------------------------  
  97. //转换  
  98. static int rgb565_to_rgb888(const void * psrc, int w, int h, void * pdst)  
  99. {  
  100.     int srclinesize = UpAlign4(w * 2);  
  101.     int dstlinesize = UpAlign4(w * 3);  
  102.   
  103.     const unsigned char  * psrcline;  
  104.     const unsigned short * psrcdot;  
  105.     unsigned char  * pdstline;  
  106.     unsigned char  * pdstdot;  
  107.   
  108.     int i,j;  
  109.   
  110.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  111.         printf("rgb565_to_rgb888 : parameter error\n");  
  112.         return -1;  
  113.     }  
  114.   
  115.     psrcline = (const unsigned char *)psrc;  
  116.     pdstline = (unsigned char *)pdst;  
  117.     for (i=0; i<h; i++) {  
  118.         psrcdot = (const unsigned short *)psrcline;  
  119.         pdstdot = pdstline;  
  120.         for (j=0; j<w; j++) {  
  121.             //565 b|g|r -> 888 r|g|b  
  122.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 0 ) << 3);  
  123.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 5 ) << 2);  
  124.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 11) << 3);  
  125.             psrcdot++;  
  126.         }  
  127.         psrcline += srclinesize;  
  128.         pdstline += dstlinesize;  
  129.     }  
  130.   
  131.     return 0;  
  132. }  
  133.   
  134. static int rgb888_to_rgb565(const void * psrc, int w, int h, void * pdst)  
  135. {  
  136.     int srclinesize = UpAlign4(w * 3);  
  137.     int dstlinesize = UpAlign4(w * 2);  
  138.       
  139.     const unsigned char * psrcline;  
  140.     const unsigned char * psrcdot;  
  141.     unsigned char  * pdstline;  
  142.     unsigned short * pdstdot;  
  143.       
  144.     int i,j;  
  145.       
  146.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  147.         printf("rgb888_to_rgb565 : parameter error\n");  
  148.         return -1;  
  149.     }  
  150.   
  151.     psrcline = (const unsigned char *)psrc;  
  152.     pdstline = (unsigned char *)pdst;  
  153.     for (i=0; i<h; i++) {  
  154.         psrcdot = psrcline;  
  155.         pdstdot = (unsigned short *)pdstline;  
  156.         for (j=0; j<w; j++) {  
  157.             //888 r|g|b -> 565 b|g|r  
  158.             *pdstdot =  (((psrcdot[0] >> 3) & 0x1F) << 0)//r  
  159.                         |(((psrcdot[1] >> 2) & 0x3F) << 5)//g  
  160.                         |(((psrcdot[2] >> 3) & 0x1F) << 11);//b  
  161.             psrcdot += 3;  
  162.             pdstdot++;  
  163.         }  
  164.         psrcline += srclinesize;  
  165.         pdstline += dstlinesize;  
  166.     }  
  167.   
  168.     return 0;  
  169. }  
  170.   
  171. static int rgb565_to_rgbx8888(const void * psrc, int w, int h, void * pdst)  
  172. {  
  173.     int srclinesize = UpAlign4(w * 2);  
  174.     int dstlinesize = UpAlign4(w * 4);  
  175.   
  176.     const unsigned char  * psrcline;  
  177.     const unsigned short * psrcdot;  
  178.     unsigned char  * pdstline;  
  179.     unsigned char  * pdstdot;  
  180.   
  181.     int i,j;  
  182.   
  183.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  184.         printf("rgb565_to_rgbx8888 : parameter error\n");  
  185.         return -1;  
  186.     }  
  187.   
  188.     psrcline = (const unsigned char *)psrc;  
  189.     pdstline = (unsigned char *)pdst;  
  190.     for (i=0; i<h; i++) {  
  191.         psrcdot = (const unsigned short *)psrcline;  
  192.         pdstdot = pdstline;  
  193.         for (j=0; j<w; j++) {  
  194.             pdstdot++;  
  195.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 0 ) << 3);  
  196.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 5 ) << 2);  
  197.             *pdstdot++ = (unsigned char)(((*psrcdot) >> 11) << 3);  
  198.             psrcdot++;  
  199.         }  
  200.         psrcline += srclinesize;  
  201.         pdstline += dstlinesize;  
  202.     }  
  203.       
  204.     return 0;  
  205. }  
  206.   
  207. static int rgbx8888_to_rgb565(const void * psrc, int w, int h, void * pdst)  
  208. {  
  209.     int srclinesize = UpAlign4(w * 4);  
  210.     int dstlinesize = UpAlign4(w * 2);  
  211.       
  212.     const unsigned char * psrcline;  
  213.     const unsigned char * psrcdot;  
  214.     unsigned char  * pdstline;  
  215.     unsigned short * pdstdot;  
  216.       
  217.     int i,j;  
  218.       
  219.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  220.         printf("rgbx8888_to_rgb565 : parameter error\n");  
  221.         return -1;  
  222.     }  
  223.       
  224.     psrcline = (const unsigned char *)psrc;  
  225.     pdstline = (unsigned char *)pdst;  
  226.     for (i=0; i<h; i++) {  
  227.         psrcdot = psrcline;  
  228.         pdstdot = (unsigned short *)pdstline;  
  229.         for (j=0; j<w; j++) {  
  230.             //888 r|g|b -> 565 b|g|r  
  231.             *pdstdot =  (((psrcdot[1] >> 3) & 0x1F) << 0)//r  
  232.                 |(((psrcdot[2] >> 2) & 0x3F) << 5)//g  
  233.                 |(((psrcdot[3] >> 3) & 0x1F) << 11);//b  
  234.             psrcdot += 4;  
  235.             pdstdot++;  
  236.         }  
  237.         psrcline += srclinesize;  
  238.         pdstline += dstlinesize;  
  239.     }  
  240.       
  241.     return 0;  
  242. }  
  243.   
  244. static int rgb888_to_rgbx8888(const void * psrc, int w, int h, void * pdst)  
  245. {  
  246.     int srclinesize = UpAlign4(w * 3);  
  247.     int dstlinesize = UpAlign4(w * 4);  
  248.   
  249.     const unsigned char * psrcline;  
  250.     const unsigned char * psrcdot;  
  251.     unsigned char  * pdstline;  
  252.     unsigned char  * pdstdot;  
  253.   
  254.     int i,j;  
  255.   
  256.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  257.         printf("rgb888_to_rgbx8888 : parameter error\n");  
  258.         return -1;  
  259.     }  
  260.   
  261.     psrcline = (const unsigned char *)psrc;  
  262.     pdstline = (unsigned char *)pdst;  
  263.     for (i=0; i<h; i++) {  
  264.         psrcdot = psrcline;  
  265.         pdstdot = pdstline;  
  266.         for (j=0; j<w; j++) {  
  267.             *pdstdot++ = 0;  
  268.             *pdstdot++ = *psrcdot++;  
  269.             *pdstdot++ = *psrcdot++;  
  270.             *pdstdot++ = *psrcdot++;  
  271.         }  
  272.         psrcline += srclinesize;  
  273.         pdstline += dstlinesize;  
  274.     }  
  275.       
  276.     return 0;  
  277. }  
  278.   
  279. static int rgbx8888_to_rgb888(const void * psrc, int w, int h, void * pdst)  
  280. {  
  281.     int srclinesize = UpAlign4(w * 4);  
  282.     int dstlinesize = UpAlign4(w * 3);  
  283.       
  284.     const unsigned char * psrcline;  
  285.     const unsigned char * psrcdot;  
  286.     unsigned char  * pdstline;  
  287.     unsigned char  * pdstdot;  
  288.       
  289.     int i,j;  
  290.       
  291.     if (!psrc || !pdst || w <= 0 || h <= 0) {  
  292.         printf("rgbx8888_to_rgb888 : parameter error\n");  
  293.         return -1;  
  294.     }  
  295.       
  296.     psrcline = (const unsigned char *)psrc;  
  297.     pdstline = (unsigned char *)pdst;  
  298.     for (i=0; i<h; i++) {  
  299.         psrcdot = psrcline;  
  300.         pdstdot = pdstline;  
  301.         for (j=0; j<w; j++) {  
  302.             psrcdot++;  
  303.             *pdstdot++ = *psrcdot++;  
  304.             *pdstdot++ = *psrcdot++;  
  305.             *pdstdot++ = *psrcdot++;  
  306.         }  
  307.         psrcline += srclinesize;  
  308.         pdstline += dstlinesize;  
  309.     }  
  310.       
  311.     return 0;  
  312. }  
  313.   
  314. void * rgb565_to_rgb888_buffer(const void * psrc, int w, int h)  
  315. {  
  316.     int size = h * UpAlign4(w * 3);  
  317.     void * pdst = NULL;  
  318.     if (psrc && w > 0 && h > 0) {  
  319.         pdst = malloc(size);  
  320.         if (pdst) {  
  321.             if (rgb565_to_rgb888(psrc, w, h, pdst)) {  
  322.                 free(pdst);  
  323.                 pdst = NULL;  
  324.             }  
  325.         }  
  326.     }  
  327.     return pdst;  
  328. }  
  329.   
  330. void * rgb888_to_rgb565_buffer(const void * psrc, int w, int h)  
  331. {  
  332.     int size = h * UpAlign4(w * 2);  
  333.     void * pdst = NULL;  
  334.     if (psrc && w > 0 && h > 0) {  
  335.         pdst = malloc(size);  
  336.         if (pdst) {  
  337.             if (rgb888_to_rgb565(psrc, w, h, pdst)) {  
  338.                 free(pdst);  
  339.                 pdst = NULL;  
  340.             }  
  341.         }  
  342.     }  
  343.     return pdst;  
  344. }  
  345.   
  346. void * rgb565_to_rgbx8888_buffer(const void * psrc, int w, int h)  
  347. {  
  348.     int size = h * UpAlign4(w * 4);  
  349.     void * pdst = NULL;  
  350.     if (psrc && w > 0 && h > 0) {  
  351.         pdst = malloc(size);  
  352.         if (pdst) {  
  353.             if (rgb565_to_rgbx8888(psrc, w, h, pdst)) {  
  354.                 free(pdst);  
  355.                 pdst = NULL;  
  356.             }  
  357.         }  
  358.     }  
  359.     return pdst;  
  360. }  
  361.   
  362. void * rgbx8888_to_rgb565_buffer(const void * psrc, int w, int h)  
  363. {  
  364.     int size = h * UpAlign4(w * 2);  
  365.     void * pdst = NULL;  
  366.     if (psrc && w > 0 && h > 0) {  
  367.         pdst = malloc(size);  
  368.         if (pdst) {  
  369.             if (rgbx8888_to_rgb565(psrc, w, h, pdst)) {  
  370.                 free(pdst);  
  371.                 pdst = NULL;  
  372.             }  
  373.         }  
  374.     }  
  375.     return pdst;  
  376. }  
  377.   
  378. void * rgb888_to_rgbx8888_buffer(const void * psrc, int w, int h)  
  379. {  
  380.     int size = h * UpAlign4(w * 4);  
  381.     void * pdst = NULL;  
  382.     if (psrc && w > 0 && h > 0) {  
  383.         pdst = malloc(size);  
  384.         if (pdst) {  
  385.             if (rgb888_to_rgbx8888(psrc, w, h, pdst)) {  
  386.                 free(pdst);  
  387.                 pdst = NULL;  
  388.             }  
  389.         }  
  390.     }  
  391.     return pdst;  
  392. }  
  393.   
  394. void * rgbx8888_to_rgb888_buffer(const void * psrc, int w, int h)  
  395. {  
  396.     int size = h * UpAlign4(w * 3);  
  397.     void * pdst = NULL;  
  398.     if (psrc && w > 0 && h > 0) {  
  399.         pdst = malloc(size);  
  400.         if (pdst) {  
  401.             if (rgbx8888_to_rgb888(psrc, w, h, pdst)) {  
  402.                 free(pdst);  
  403.                 pdst = NULL;  
  404.             }  
  405.         }  
  406.     }  
  407.     return pdst;  
  408. }  
  409.   
  410. static const RGB_CONVERT_FUN g_convert_func[3][3] =   
  411. {  
  412.     {NULL, rgb565_to_rgb888_buffer, rgb565_to_rgbx8888_buffer},  
  413.     {rgb888_to_rgb565_buffer, NULL, rgb888_to_rgbx8888_buffer},  
  414.     {rgbx8888_to_rgb565_buffer, rgbx8888_to_rgb888_buffer, NULL}  
  415. };  
  416.   
  417. RGB_CONVERT_FUN get_convert_func(int frombpp, int tobpp)  
  418. {  
  419.     RGB_CONVERT_FUN func_ptr = NULL;  
  420.     frombpp = UpAlign8(frombpp) / 8 - 2;  
  421.     tobpp = UpAlign8(tobpp) / 8 - 2;  
  422.     if ((frombpp >= 0 && frombpp <= 2)  
  423.         && (tobpp >= 0 && tobpp <= 2)) {  
  424.         func_ptr = g_convert_func[frombpp][tobpp];  
  425.     }  
  426.     return func_ptr;  
  427. }  
  428.   
  429. //-------------------------------------------------------------------  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多