Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ImageConversions.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h> /* for phDALLOC_QUIET_VOIDRETURN,PHAPI */
00031 #include <ImageUtil.h>
00032 #include <ImageConversions.h>
00033 #include <ImageDefinitions.h>
00034 #include <phMath.h>
00035 #include <phError.h>
00036 #include <phMemory.h>
00037 #include <phPrint.h>
00038 
00039 #ifdef __cplusplus
00040 extern "C" 
00041 {
00042 #endif /* __cplusplus */
00043 
00044 /* ---------------------------------------------------------------------- */
00050 typedef struct ph_convert_func_struct
00051 {
00053     uint32_t                out_format;
00055     uint32_t                in_format;
00058     const char *            name;
00061     ph_inplace_convert_fn   i_convert;
00064     ph_copy_convert_fn      c_convert;
00065 } ph_convert_func_type;
00066 
00067 /* ---------------------------------------------------------------------- */
00073 #define phCONVERT_FUNC(in,out,name,i_func,c_func) \
00074     {in,out,name,i_func,c_func},
00075 
00076 /* ---------------------------------------------------------------------- */
00081 #define phCONVERT_TABLE(nformats) \
00082     static const uint32_t ph_glbl_convert_func_stride=nformats;   \
00083     static const uint32_t ph_glbl_convert_func_total =(nformats * nformats);\
00084                                                                             \
00085     static ph_convert_func_type                                             \
00086         ph_glbl_convert_func_table[(nformats*nformats)+1] = {
00087         
00088 /* ---------------------------------------------------------------------- */
00094 #define phCONVERT_TABLE_END() \
00095     {phImageNOFORMAT,phImageNOFORMAT,"end-of-list",ph_iNULL,ph_cNULL} \
00096 };
00097 
00098 /* ---------------------------------------------------------------------- */
00106 phCONVERT_TABLE(9)
00107 /*              out            in       name , in-place  copy-to-dst                */
00108 phCONVERT_FUNC(phImageRGB24,phImageRGB24,   "empty:RGB24",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00109 phCONVERT_FUNC(phImageRGB24,phImageBGR24,   "phBGR24_to_RGB24",phBGR24_to_RGB24,ph_cNULL)
00110 phCONVERT_FUNC(phImageRGB24,phImageABGR32,  "phABGR32_to_RGB24_ex",ph_iNULL,phABGR32_to_RGB24_ex)
00111 phCONVERT_FUNC(phImageRGB24,phImageBGRA32,  "phBGRA32_to_RGB24_ex",ph_iNULL,phBGRA32_to_RGB24_ex)
00112 phCONVERT_FUNC(phImageRGB24,phImageRGBA32,  "phRGBA32_to_RGB24_ex",ph_iNULL,phRGBA32_to_RGB24_ex)
00113 phCONVERT_FUNC(phImageRGB24,phImageGREY8,   "phGREY8_to_RGB24_ex",ph_iNULL,phGREY8_to_RGB24_ex)
00114 phCONVERT_FUNC(phImageRGB24,phImageYUV9,    "phYUV9_to_RGB24_ex",ph_iNULL,phYUV9_to_RGB24_ex)
00115 phCONVERT_FUNC(phImageRGB24,phImageHSV24,   "phHSV24_to_RGB24_ex",ph_iNULL,phHSV24_to_RGB24_ex)
00116 phCONVERT_FUNC(phImageRGB24,phImageSCT24,   "phSCT24_to_RGB24",ph_iNULL,phSCT24_to_RGB24_ex)
00117     
00118 /*              out            in       name , in-place  copy-to-dst                */
00119 phCONVERT_FUNC(phImageBGR24,phImageRGB24,   "phRGB24_to_BGR24",phRGB24_to_BGR24,ph_cNULL)
00120 phCONVERT_FUNC(phImageBGR24,phImageBGR24,   "empty:BGR24",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00121 phCONVERT_FUNC(phImageBGR24,phImageABGR32,  "phABGR32_to_BGR24_ex",ph_iNULL,phABGR32_to_BGR24_ex)
00122 phCONVERT_FUNC(phImageBGR24,phImageBGRA32,  "phBGRA32_to_BGR24_ex",ph_iNULL,phBGRA32_to_BGR24_ex)
00123 phCONVERT_FUNC(phImageBGR24,phImageRGBA32,  "phRGBA32_to_BGR24_ex",ph_iNULL,phRGBA32_to_BGR24_ex)
00124 phCONVERT_FUNC(phImageBGR24,phImageGREY8,   "phGREY8_to_BGR24_ex",ph_iNULL,phGREY8_to_BGR24_ex)
00125 phCONVERT_FUNC(phImageBGR24,phImageYUV9,    "phYUV9_to_BGR24_ex",ph_iNULL,phYUV9_to_BGR24_ex)
00126 phCONVERT_FUNC(phImageBGR24,phImageHSV24,   "phHSV24_to_BGR24_ex",ph_iNULL,phHSV24_to_BGR24_ex)
00127 phCONVERT_FUNC(phImageBGR24,phImageSCT24,   "phSCT24_to_BGR24",ph_iNULL,phSCT24_to_BGR24_ex)
00128     
00129 /*              out            in       name , in-place  copy-to-dst                */
00130 phCONVERT_FUNC(phImageABGR32,phImageRGB24,  "phRGB24_to_ABGR32_ex",ph_iNULL,phRGB24_to_ABGR32_ex)
00131 phCONVERT_FUNC(phImageABGR32,phImageBGR24,  "phBGR24_to_ABGR32_ex",ph_iNULL,phBGR24_to_ABGR32_ex)
00132 phCONVERT_FUNC(phImageABGR32,phImageABGR32, "empty:ABGR32",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00133 phCONVERT_FUNC(phImageABGR32,phImageBGRA32, "phBGRA32_to_ABGR32_ex",phBGRA32_to_ABGR32_ex,ph_cNULL)
00134 phCONVERT_FUNC(phImageABGR32,phImageRGBA32, "phRGBA32_to_ABGR32",phRGBA32_to_ABGR32,ph_cNULL)
00135 phCONVERT_FUNC(phImageABGR32,phImageGREY8,  "phGREY8_to_ABGR32_ex",ph_iNULL,phGREY8_to_ABGR32_ex)
00136 phCONVERT_FUNC(phImageABGR32,phImageYUV9,   "phYUV9_to_ABGR32_ex",ph_iNULL,phYUV9_to_ABGR32_ex)
00137 phCONVERT_FUNC(phImageABGR32,phImageHSV24,  "phHSV24_to_ABGR32_ex",ph_iNULL,phHSV24_to_ABGR32_ex)
00138 phCONVERT_FUNC(phImageABGR32,phImageSCT24,   "phSCT24_to_ABGR32",ph_iNULL,phSCT24_to_ABGR32_ex)
00139     
00140 /*              out            in       name , in-place  copy-to-dst                */
00141 phCONVERT_FUNC(phImageBGRA32,phImageRGB24,   "phRGB24_to_BGRA32_ex",ph_iNULL,phRGB24_to_BGRA32_ex)
00142 phCONVERT_FUNC(phImageBGRA32,phImageBGR24,   "phBGR24_to_BGRA32_ex",ph_iNULL,phBGR24_to_BGRA32_ex)
00143 phCONVERT_FUNC(phImageBGRA32,phImageABGR32,  "phABGR32_to_BGRA32_ex",phABGR32_to_BGRA32_ex,ph_cNULL)
00144 phCONVERT_FUNC(phImageBGRA32,phImageBGRA32,  "empty:BGRA32",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00145 phCONVERT_FUNC(phImageBGRA32,phImageRGBA32,  "phRGBA32_to_BGRA32",phRGBA32_to_BGRA32,ph_cNULL)
00146 phCONVERT_FUNC(phImageBGRA32,phImageGREY8,   "phGREY8_to_BGRA32_ex",ph_iNULL,phGREY8_to_BGRA32_ex)
00147 phCONVERT_FUNC(phImageBGRA32,phImageYUV9,    "phYUV9_to_BGRA32_ex",ph_iNULL,phYUV9_to_BGRA32_ex)
00148 phCONVERT_FUNC(phImageBGRA32,phImageHSV24,   "phHSV24_to_BGRA32_ex",ph_iNULL,phHSV24_to_BGRA32_ex)
00149 phCONVERT_FUNC(phImageBGRA32,phImageSCT24,   "phSCT24_to_BGRA32",ph_iNULL,phSCT24_to_BGRA32_ex)
00150  
00151 /*              out            in       name , in-place  copy-to-dst                */
00152 phCONVERT_FUNC(phImageRGBA32,phImageRGB24,  "phRGB24_to_RGBA32_ex",ph_iNULL,phRGB24_to_RGBA32_ex)
00153 phCONVERT_FUNC(phImageRGBA32,phImageBGR24,  "phBGR24_to_RGBA32_ex",ph_iNULL,phBGR24_to_RGBA32_ex)
00154 phCONVERT_FUNC(phImageRGBA32,phImageABGR32, "phABGR32_to_RGBA32",phABGR32_to_RGBA32,ph_cNULL)
00155 phCONVERT_FUNC(phImageRGBA32,phImageBGRA32, "phBGRA32_to_RGBA32",phBGRA32_to_RGBA32,ph_cNULL)
00156 phCONVERT_FUNC(phImageRGBA32,phImageRGBA32, "empty:RGBA32",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00157 phCONVERT_FUNC(phImageRGBA32,phImageGREY8,  "phGREY8_to_RGBA32_ex",ph_iNULL,phGREY8_to_RGBA32_ex)
00158 phCONVERT_FUNC(phImageRGBA32,phImageYUV9,   "phYUV9_to_RGBA32_ex",ph_iNULL,phYUV9_to_RGBA32_ex)
00159 phCONVERT_FUNC(phImageRGBA32,phImageHSV24,  "phHSV24_to_RGBA32_ex",ph_iNULL,phHSV24_to_RGBA32_ex)
00160 phCONVERT_FUNC(phImageRGBA32,phImageSCT24,  "phSCT24_to_RGBA32",ph_iNULL,phSCT24_to_RGBA32_ex)
00161     
00162 /*              out            in       name , in-place  copy-to-dst                */
00163 phCONVERT_FUNC(phImageGREY8,phImageRGB24,   "phRGB24_to_GREY8_ex",ph_iNULL,phRGB24_to_GREY8_ex)
00164 phCONVERT_FUNC(phImageGREY8,phImageBGR24,   "phBGR24_to_GREY8_ex",ph_iNULL,phBGR24_to_GREY8_ex)
00165 phCONVERT_FUNC(phImageGREY8,phImageABGR32,  "phABGR32_to_GREY8_ex",ph_iNULL,phABGR32_to_GREY8_ex)
00166 phCONVERT_FUNC(phImageGREY8,phImageBGRA32,  "phBGRA32_to_GREY8_ex",ph_iNULL,phBGRA32_to_GREY8_ex)
00167 phCONVERT_FUNC(phImageGREY8,phImageRGBA32,  "phRGBA32_to_GREY8_ex",ph_iNULL,phRGBA32_to_GREY8_ex)
00168 phCONVERT_FUNC(phImageGREY8,phImageGREY8,   "empty:GREY8",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00169 phCONVERT_FUNC(phImageGREY8,phImageYUV9,    "phYUV9_to_GREY8_ex",ph_iNULL,phYUV9_to_GREY8_ex)
00170 phCONVERT_FUNC(phImageGREY8,phImageHSV24,   "todo:HSV24_to_GREY8",ph_iNULL,ph_cNULL) /* TODO */
00171 phCONVERT_FUNC(phImageGREY8,phImageSCT24,   "todo:SCT24_to_GREY8",ph_iNULL,ph_cNULL) /* TODO */
00172     
00173 /*              out            in       name , in-place  copy-to-dst                */
00174 phCONVERT_FUNC(phImageYUV9,phImageRGB24,    "phRGB24_to_YUV9_ex",ph_iNULL,phRGB24_to_YUV9_ex)
00175 phCONVERT_FUNC(phImageYUV9,phImageBGR24,    "phBGR24_to_YUV9_ex",ph_iNULL,phBGR24_to_YUV9_ex)
00176 phCONVERT_FUNC(phImageYUV9,phImageABGR32,   "phABGR32_to_YUV9_ex",ph_iNULL,phABGR32_to_YUV9_ex)
00177 phCONVERT_FUNC(phImageYUV9,phImageBGRA32,   "phBGRA32_to_YUV9_ex",ph_iNULL,phBGRA32_to_YUV9_ex)
00178 phCONVERT_FUNC(phImageYUV9,phImageRGBA32,   "phRGBA32_to_YUV9_ex",ph_iNULL,phRGBA32_to_YUV9_ex)
00179 phCONVERT_FUNC(phImageYUV9,phImageGREY8,    "phGREY8_to_YUV9_ex",ph_iNULL,phGREY8_to_YUV9_ex)
00180 phCONVERT_FUNC(phImageYUV9,phImageYUV9,     "empty:YUV9",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00181 phCONVERT_FUNC(phImageYUV9,phImageHSV24,    "todo:HSV24_to_YUV9",ph_iNULL,ph_cNULL) /* TODO */
00182 phCONVERT_FUNC(phImageYUV9,phImageSCT24,    "todo:SCT24_to_YUV9",ph_iNULL,ph_cNULL) /* TODO */
00183     
00184 /*              out            in       name , in-place  copy-to-dst                */
00185 phCONVERT_FUNC(phImageHSV24,phImageRGB24,   "phRGB24_to_HSV24_ex",ph_iNULL,phRGB24_to_HSV24_ex)
00186 phCONVERT_FUNC(phImageHSV24,phImageBGR24,   "phBGR24_to_HSV24_ex",ph_iNULL,phBGR24_to_HSV24_ex)
00187 phCONVERT_FUNC(phImageHSV24,phImageABGR32,  "phABGR32_to_HSV24_ex",ph_iNULL,phABGR32_to_HSV24_ex)
00188 phCONVERT_FUNC(phImageHSV24,phImageBGRA32,  "phBGRA32_to_HSV24_ex",ph_iNULL,phBGRA32_to_HSV24_ex)
00189 phCONVERT_FUNC(phImageHSV24,phImageRGBA32,  "phRGBA32_to_HSV24_ex",ph_iNULL,phRGBA32_to_HSV24_ex)
00190 phCONVERT_FUNC(phImageHSV24,phImageGREY8,   "todo:GREY8_to_HSV24",ph_iNULL,ph_cNULL) /* TODO */
00191 phCONVERT_FUNC(phImageHSV24,phImageYUV9,    "todo:YUV9_to_HSV24",ph_iNULL,ph_cNULL) /* TODO */
00192 phCONVERT_FUNC(phImageHSV24,phImageHSV24,   "empty:HSV24",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00193 phCONVERT_FUNC(phImageHSV24,phImageSCT24,   "todo:SCT24_to_HSV24",ph_iNULL,ph_cNULL) /* TODO */
00194 
00195 /*              out            in       name , in-place  copy-to-dst                */
00196 phCONVERT_FUNC(phImageSCT24,phImageRGB24,   "phRGB24_to_SCT24",ph_iNULL,phRGB24_to_SCT24_ex)
00197 phCONVERT_FUNC(phImageSCT24,phImageBGR24,   "phBGR24_to_SCT24",ph_iNULL,phBGR24_to_SCT24_ex)
00198 phCONVERT_FUNC(phImageSCT24,phImageABGR32,  "phABGR32_to_SCT24_ex",ph_iNULL,phABGR32_to_SCT24_ex)
00199 phCONVERT_FUNC(phImageSCT24,phImageBGRA32,  "phBGRA32_to_SCT24_ex",ph_iNULL,phBGRA32_to_SCT24_ex)
00200 phCONVERT_FUNC(phImageSCT24,phImageRGBA32,  "phRGBA32_to_SCT24_ex",ph_iNULL,phRGBA32_to_SCT24_ex)
00201 phCONVERT_FUNC(phImageSCT24,phImageGREY8,   "todo:GREY8_to_SCT24",ph_iNULL,ph_cNULL) /* TODO */
00202 phCONVERT_FUNC(phImageSCT24,phImageYUV9,    "todo:YUV9_to_SCT24",ph_iNULL,ph_cNULL) /* TODO */
00203 phCONVERT_FUNC(phImageHSV24,phImageHSV24,   "todo:HSV24_to_SCT24",ph_iNULL,ph_cNULL) /* TODO */
00204 phCONVERT_FUNC(phImageSCT24,phImageSCT24,   "empty:SCT24",ph_iNULL,ph_cNULL) /* EMPTY TRANSFORM */
00205 
00206 
00207 phCONVERT_TABLE_END()
00208     
00209 /* ---------------------------------------------------------------------- */
00210 int ph_image_convert(uint32_t    width,
00211                      uint32_t    height,
00212                      uint8_t     *data,
00213                      /* dst: if conversion not done in place
00214                       * data is placed here */
00215                      uint8_t     **dst,
00216                     /* dst_size: if conversion not done 
00217                      * in place, size of dst if already allocated or 0 */
00218                      uint32_t    *dst_size,
00219                      uint32_t    *dst_format,
00220                      uint32_t    in_format, 
00221                      uint32_t    out_format,
00222                      int32_t     *conversion_type
00223                     )
00224 {
00225     phFUNCTION("ph_image_convert")
00226     int                     retrc           = phSUCCESS;
00227     uint32_t                i               = 0;
00228     uint32_t                j               = 0;
00229     ph_convert_func_type   *fptr            = NULL;
00230     uint32_t                fptr_out_format = phImageNOFORMAT;
00231     
00232     /* Defined global convert variables:
00233      * 
00234      * ph_glbl_convert_func_total
00235      * ph_glbl_convert_func_table
00236      * ph_glbl_convert_func_stride
00237      *
00238      */
00239     for (i = 0; (fptr == NULL) && (i < ph_glbl_convert_func_total); i++ )
00240     {
00241         if (ph_glbl_convert_func_table[i].out_format & out_format)
00242         {
00243             DEBUG_PRINT("0x%08x & 0x%08x\n",
00244                      ph_glbl_convert_func_table[i].out_format,
00245                      out_format);
00246             for (j = 0; 
00247                  ((fptr == NULL) &&
00248                   ((j < ph_glbl_convert_func_stride) && 
00249                    (i < ph_glbl_convert_func_total))); 
00250                  i++, j++ )
00251             {
00252                 if (ph_glbl_convert_func_table[i].in_format & in_format)
00253                 {
00254                     fptr = &(ph_glbl_convert_func_table[i]);
00255                     fptr_out_format = ph_glbl_convert_func_table[i].out_format;
00256                 }
00257             }
00258         }
00259         /* Since the methods are organized by out_format, jump to the
00260          * next group to speed things up */
00261         else
00262         {
00263             i += (ph_glbl_convert_func_stride - 1); /* -1 because of i++ */
00264         }
00265     }
00266 
00267     if (fptr == NULL)
00268     {
00269         phERR_PRINT("Unsupported image format type\n");
00270         retrc = phFAIL;
00271     }
00272     else
00273     {
00274         /* an in place conversion */
00275         if (fptr->i_convert != NULL)
00276         {
00277             (fptr->i_convert)(width,height,data);
00278             if (dst_format != NULL)
00279             {
00280                 (*dst_format) = fptr_out_format;
00281             }
00282             if (conversion_type != NULL)
00283             {
00284                 (*conversion_type) = phImageCONVERT_INPLACE;
00285             }
00286         }
00287         /* A copy to dst conversion */
00288         else if (fptr->c_convert != NULL)
00289         {
00290             (fptr->c_convert)(width,height,data,dst,dst_size);
00291 
00292             if (*dst == NULL)
00293             {
00294                 phERR_PRINT("Failed to convert data from[%s] to [%s].\n",
00295                         phImageFormatToString(in_format),
00296                         phImageFormatToString(out_format));
00297             }
00298             else if (dst_format != NULL) 
00299             {
00300                 (*dst_format) = fptr_out_format;
00301             }
00302             if (conversion_type != NULL)
00303             {
00304                 (*conversion_type) = phImageCONVERT_COPY;
00305             }
00306         }
00307         /* No function to do the conversion */
00308         else
00309         {
00310             if (conversion_type != NULL)
00311             {
00312                 (*conversion_type) = phImageCONVERT_FAIL;
00313             }
00314             retrc = phFAIL;
00315         }
00316     }
00317     
00318     return retrc;
00319 }
00320 /* ---------------------------------------------------------------------- */
00321 void phBGRA32_to_RGBA32(uint32_t w,uint32_t h,uint8_t *data) {
00322     phBGRA32_x_RGBA32(w*h*4,data);
00323 }
00324 void phRGBA32_to_BGRA32(uint32_t w,uint32_t h,uint8_t *data) {
00325     phBGRA32_x_RGBA32(w*h*4,data);
00326 }
00327 void phBGRA32_to_ABGR32_ex( uint32_t w, uint32_t h, uint8_t *data) {
00328     phBGRA32_to_ABGR32(w*h*4,data);
00329 }
00330 void phABGR32_to_BGRA32_ex( uint32_t w, uint32_t h, uint8_t *data) {
00331     phABGR32_to_BGRA32(w*h*4,data);
00332 }
00333 void phBGR24_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00334     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,0,src,dst,pdstsize);
00335 }
00336 void phBGR24_to_BGRA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00337     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,0,src,dst,NULL);
00338 }
00339 void phBGRA32_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00340     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,0,0,src,dst,pdstsize);
00341 }
00342 void phBGRA32_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00343     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,0,0,src,dst,NULL);
00344 }
00345 void phBGRA32_to_RGB24_ex(uint32_t w, uint32_t h,uint8_t *src, uint8_t **dst,uint32_t *pdstsize) {
00346     phBGRA32_x_RGBA32(w*h*4,src);
00347     phRGBA32_to_RGB24_ex(w,h,src,dst,pdstsize);
00348 }
00349 void phBGRA32_to_RGB24(uint32_t w, uint32_t h,uint8_t *src, uint8_t **dst) {
00350     phBGRA32_x_RGBA32(w*h*4,src);
00351     phRGBA32_to_RGB24(w,h,src,dst);
00352 }
00353 
00354 /* ---------------------------------------------------------------------- */
00355 void phBGR24_to_RGB24(uint32_t w,uint32_t h,uint8_t *data) {
00356     phBGR24_x_RGB24(w*h*3,data);
00357 }
00358 void phRGB24_to_BGR24(uint32_t w,uint32_t h,uint8_t *data) {
00359     phBGR24_x_RGB24(w*h*3,data);
00360 }
00361 void phABGR32_to_RGBA32(uint32_t w,uint32_t h,uint8_t *data) {
00362     phABGR32_x_RGBA32(w*h*4,data);
00363 }
00364 void phRGBA32_to_ABGR32(uint32_t w,uint32_t h,uint8_t *data) {
00365     phABGR32_x_RGBA32(w*h*4,data);
00366 }
00367 void phRGB24_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00368     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,0,src,dst,NULL);
00369 }
00370 void phBGR24_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00371     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,1,src,dst,NULL);
00372 }
00373 void phRGBA32_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00374     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,0,0,src,dst,NULL);
00375 }
00376 void phABGR32_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00377     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,1,0,src,dst,NULL);
00378 }
00379 void phGREY8_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00380     phVECTOR_BLOCK_COPY(w * h,1,1,3,3,0,0,src,dst,NULL);
00381 }
00382 void phGREY8_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00383     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,0,src,dst,NULL);
00384 }
00385 void phGREY8_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00386     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,0,src,dst,NULL);
00387 }
00388 void phGREY8_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00389     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,1,src,dst,NULL);
00390 }
00391 void phYUV9_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00392     phVECTOR_BLOCK_COPY(w * h,1,1,1,w*h,0,0,src,dst,NULL);
00393 }
00394 void phRGB24_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00395     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,0,src,dst,pdstsize);
00396 }
00397 void phBGR24_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00398     phVECTOR_BLOCK_COPY(w * h,3,3,4,3,0,1,src,dst,pdstsize);
00399 }
00400 void phRGBA32_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00401     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,0,0,src,dst,pdstsize);
00402 }
00403 void phABGR32_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00404     phVECTOR_BLOCK_COPY(w * h,4,4,3,3,1,0,src,dst,pdstsize);
00405 }
00406 void phGREY8_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00407     phVECTOR_BLOCK_COPY(w * h,1,1,3,3,0,0,src,dst,pdstsize);
00408 }
00409 void phGREY8_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00410     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,0,src,dst,pdstsize);
00411 }
00412 void phGREY8_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00413     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,0,src,dst,pdstsize);
00414 }
00415 void phGREY8_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00416     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,0,src,dst,pdstsize);
00417 }
00418 void phGREY8_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00419     phVECTOR_BLOCK_COPY(w * h,1,1,4,3,0,1,src,dst,pdstsize);
00420 }
00421 void phYUV9_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00422     phVECTOR_BLOCK_COPY(w * h,1,1,1,w*h,0,0,src,dst,pdstsize);
00423 }
00424 void phGREY8_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00425     phGREY8_to_YUV9_ex( w, h, src, dst, NULL);
00426 }
00427 void phABGR32_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00428     phABGR32_to_BGR24(w,h,src,dst);
00429     phBGR24_to_RGB24(w,h,*(dst));
00430 }
00431 void phRGBA32_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00432     phRGBA32_to_RGB24(w,h,src,dst);
00433     phRGB24_to_BGR24(w,h,*(dst));
00434 }
00435 void phBGR24_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00436     phBGR24_to_ABGR32(w,h,src,dst);
00437     phABGR32_to_RGBA32(w,h,*(dst));
00438 }
00439 void phRGB24_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00440     phRGB24_to_RGBA32(w,h,src,dst);
00441     phRGBA32_to_ABGR32(w,h,*(dst));
00442 }
00443 void phRGB24_to_BGRA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00444     phRGB24_to_RGBA32(w,h,src,dst);
00445     phRGBA32_to_BGRA32(w,h,*(dst));
00446 }
00447 void phABGR32_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00448     phABGR32_to_BGR24_ex(w,h,src,dst,pdstsize);
00449     phBGR24_to_RGB24(w,h,*(dst));
00450 }
00451 void phRGBA32_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00452     phRGBA32_to_RGB24_ex(w,h,src,dst,pdstsize);
00453     phRGB24_to_BGR24(w,h,*(dst));
00454 }
00455 void phBGR24_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00456     phBGR24_to_ABGR32_ex(w,h,src,dst,pdstsize);
00457     phABGR32_to_RGBA32(w,h,*(dst));
00458 }
00459 void phRGB24_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00460     phRGB24_to_RGBA32_ex(w,h,src,dst,pdstsize);
00461     phRGBA32_to_ABGR32(w,h,*(dst));
00462 }
00463 void phRGB24_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00464     phRGB24_to_RGBA32_ex(w,h,src,dst,pdstsize);
00465     phRGBA32_to_BGRA32(w,h,*(dst));
00466 }
00467 void phRGB24_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00468     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,3,0,0,src,dst,NULL);
00469 }
00470 void phRGBA32_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00471     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,0,0,src,dst,NULL);
00472 }
00473 void phBGR24_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00474     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,3,1,0,src,dst,NULL);
00475 }
00476 void phABGR32_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00477     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,1,1,src,dst,NULL);
00478 }
00479 void phBGRA32_to_GREY8(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00480     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,1,0,src,dst,NULL);
00481 }
00482 void phRGB24_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00483     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,3,0,0,src,dst,pdstsize);
00484 }
00485 void phRGBA32_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00486     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,0,0,src,dst,pdstsize);
00487 }
00488 void phBGR24_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00489     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,3,1,0,src,dst,pdstsize);
00490 }
00491 void phABGR32_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00492     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,1,1,src,dst,pdstsize);
00493 }
00494 void phBGRA32_to_GREY8_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00495     phRGBX_XBGR_to_GREY8_LUMINANCE(w*h,4,1,1,src,dst,pdstsize);
00496 }
00497 /* YUV */
00498 void phRGB24_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00499     phRGBX_XBGR_to_YUV9(w,h,3,0,0,src,dst,NULL);
00500 }
00501 void phRGBA32_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00502     phRGBX_XBGR_to_YUV9(w,h,4,0,0,src,dst,NULL);
00503 }
00504 void phBGR24_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00505     phRGBX_XBGR_to_YUV9(w,h,3,1,0,src,dst,NULL);
00506 }
00507 void phABGR32_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00508     phRGBX_XBGR_to_YUV9(w,h,4,1,1,src,dst,NULL);
00509 }
00510 void phBGRA32_to_YUV9(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00511     phRGBX_XBGR_to_YUV9(w,h,4,1,0,src,dst,NULL);
00512 }
00513 void phRGB24_to_YUV9_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00514     phRGBX_XBGR_to_YUV9(w,h,3,0,0,src,dst,pdstsize);
00515 }
00516 void phRGBA32_to_YUV9_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00517     phRGBX_XBGR_to_YUV9(w,h,4,0,0,src,dst,pdstsize);
00518 }
00519 void phBGR24_to_YUV9_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00520     phRGBX_XBGR_to_YUV9(w,h,3,1,0,src,dst,pdstsize);
00521 }
00522 void phABGR32_to_YUV9_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00523     phRGBX_XBGR_to_YUV9(w,h,4,1,1,src,dst,pdstsize);
00524 }
00525 void phBGRA32_to_YUV9_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00526     phRGBX_XBGR_to_YUV9(w,h,4,1,0,src,dst,pdstsize);
00527 }
00528 void phYUV9_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00529     phYUV9_to_RGBX_XBGR(w,h,3,0,0,src,dst,NULL);
00530 }
00531 void phYUV9_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00532     phYUV9_to_RGBX_XBGR(w,h,4,0,0,src,dst,NULL);
00533 }
00534 void phYUV9_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00535     phYUV9_to_RGBX_XBGR(w,h,3,1,0,src,dst,NULL);
00536 }
00537 void phYUV9_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00538     phYUV9_to_RGBX_XBGR(w,h,4,1,1,src,dst,NULL);
00539 }
00540 void phYUV9_to_BGRA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00541     phYUV9_to_RGBX_XBGR(w,h,4,1,0,src,dst,NULL);
00542 }
00543 void phYUV9_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00544     phYUV9_to_RGBX_XBGR(w,h,3,0,0,src,dst,pdstsize);
00545 }
00546 void phYUV9_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00547     phYUV9_to_RGBX_XBGR(w,h,4,0,0,src,dst,pdstsize);
00548 }
00549 void phYUV9_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00550     phYUV9_to_RGBX_XBGR(w,h,3,1,0,src,dst,pdstsize);
00551 }
00552 void phYUV9_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00553     phYUV9_to_RGBX_XBGR(w,h,4,1,1,src,dst,pdstsize);
00554 }
00555 void phYUV9_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00556     phYUV9_to_RGBX_XBGR(w,h,4,1,0,src,dst,pdstsize);
00557 }
00558 /* HSV */
00559 void phRGB24_to_HSV24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00560     phRGBX_XBGR_to_HSVX(w*h,3,3,0,0,src,dst,NULL);
00561 }
00562 void phRGBA32_to_HSV24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00563     phRGBX_XBGR_to_HSVX(w*h,4,3,0,0,src,dst,NULL);
00564 }
00565 void phBGR24_to_HSV24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00566     phRGBX_XBGR_to_HSVX(w*h,3,3,1,0,src,dst,NULL);
00567 }
00568 void phABGR32_to_HSV24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00569     phRGBX_XBGR_to_HSVX(w*h,4,3,1,1,src,dst,NULL);
00570 }
00571 void phBGRA32_to_HSV24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00572     phRGBX_XBGR_to_HSVX(w*h,4,3,1,0,src,dst,NULL);
00573 }
00574 void phRGB24_to_HSV24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00575     phRGBX_XBGR_to_HSVX(w*h,3,3,0,0,src,dst,pdstsize);
00576 }
00577 void phRGBA32_to_HSV24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00578     phRGBX_XBGR_to_HSVX(w*h,4,3,0,0,src,dst,pdstsize);
00579 }
00580 void phBGR24_to_HSV24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00581     phRGBX_XBGR_to_HSVX(w*h,3,3,1,0,src,dst,pdstsize);
00582 }
00583 void phABGR32_to_HSV24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00584     phRGBX_XBGR_to_HSVX(w*h,4,3,1,1,src,dst,pdstsize);
00585 }
00586 void phBGRA32_to_HSV24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00587     phRGBX_XBGR_to_HSVX(w*h,4,3,1,0,src,dst,pdstsize);
00588 }
00589 void phHSV24_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00590     phHSVX_to_RGBX_XBGR(w*h,3,3,0,0,src,dst,NULL);
00591 }
00592 void phHSV24_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00593     phHSVX_to_RGBX_XBGR(w*h,3,4,0,0,src,dst,NULL);
00594 }
00595 void phHSV24_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00596     phHSVX_to_RGBX_XBGR(w*h,3,3,1,0,src,dst,NULL);
00597 }
00598 void phHSV24_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00599     phHSVX_to_RGBX_XBGR(w*h,3,4,1,1,src,dst,NULL);
00600 }
00601 void phHSV24_to_BGRA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00602     phHSVX_to_RGBX_XBGR(w*h,3,4,1,0,src,dst,NULL);
00603 }
00604 void phHSV24_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00605     phHSVX_to_RGBX_XBGR(w*h,3,3,0,0,src,dst,pdstsize);
00606 }
00607 void phHSV24_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00608     phHSVX_to_RGBX_XBGR(w*h,3,4,0,0,src,dst,pdstsize);
00609 }
00610 void phHSV24_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00611     phHSVX_to_RGBX_XBGR(w*h,3,3,1,0,src,dst,pdstsize);
00612 }
00613 void phHSV24_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00614     phHSVX_to_RGBX_XBGR(w*h,3,4,1,1,src,dst,pdstsize);
00615 }
00616 void phHSV24_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00617     phHSVX_to_RGBX_XBGR(w*h,3,4,1,0,src,dst,pdstsize);
00618 }
00619 /* SCT */    
00620 
00621 void phRGB24_to_SCT24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00622     phRGBX_XBGR_to_SCTX(w*h,3,3,0,0,src,dst,NULL);
00623 }
00624 void phRGBA32_to_SCT24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00625     phRGBX_XBGR_to_SCTX(w*h,4,3,0,0,src,dst,NULL);
00626 }
00627 void phBGR24_to_SCT24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00628     phRGBX_XBGR_to_SCTX(w*h,3,3,1,0,src,dst,NULL);
00629 }
00630 void phABGR32_to_SCT24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00631     phRGBX_XBGR_to_SCTX(w*h,4,3,1,1,src,dst,NULL);
00632 }
00633 void phBGRA32_to_SCT24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00634     phRGBX_XBGR_to_SCTX(w*h,4,3,1,0,src,dst,NULL);
00635 }
00636 void phRGB24_to_SCT24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00637     phRGBX_XBGR_to_SCTX(w*h,3,3,0,0,src,dst,pdstsize);
00638 }
00639 void phRGBA32_to_SCT24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00640     phRGBX_XBGR_to_SCTX(w*h,4,3,0,0,src,dst,pdstsize);
00641 }
00642 void phBGR24_to_SCT24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00643     phRGBX_XBGR_to_SCTX(w*h,3,3,1,0,src,dst,pdstsize);
00644 }
00645 void phABGR32_to_SCT24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00646     phRGBX_XBGR_to_SCTX(w*h,4,3,1,1,src,dst,pdstsize);
00647 }
00648 void phBGRA32_to_SCT24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00649     phRGBX_XBGR_to_SCTX(w*h,4,3,1,0,src,dst,pdstsize);
00650 }
00651 void phSCT24_to_RGB24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00652     phSCTX_to_RGBX_XBGR(w*h,3,3,0,0,src,dst,NULL);
00653 }
00654 void phSCT24_to_RGBA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00655     phSCTX_to_RGBX_XBGR(w*h,3,4,0,0,src,dst,NULL);
00656 }
00657 void phSCT24_to_BGR24(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00658     phSCTX_to_RGBX_XBGR(w*h,3,3,1,0,src,dst,NULL);
00659 }
00660 void phSCT24_to_ABGR32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00661     phSCTX_to_RGBX_XBGR(w*h,3,4,1,1,src,dst,NULL);
00662 }
00663 void phSCT24_to_BGRA32(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst) {
00664     phSCTX_to_RGBX_XBGR(w*h,3,4,1,0,src,dst,NULL);
00665 }
00666 void phSCT24_to_RGB24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00667     phSCTX_to_RGBX_XBGR(w*h,3,3,0,0,src,dst,pdstsize);
00668 }
00669 void phSCT24_to_RGBA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00670     phSCTX_to_RGBX_XBGR(w*h,3,4,0,0,src,dst,pdstsize);
00671 }
00672 void phSCT24_to_BGR24_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00673     phSCTX_to_RGBX_XBGR(w*h,3,3,1,0,src,dst,pdstsize);
00674 }
00675 void phSCT24_to_ABGR32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00676     phSCTX_to_RGBX_XBGR(w*h,3,4,1,1,src,dst,pdstsize);
00677 }
00678 void phSCT24_to_BGRA32_ex(uint32_t w,uint32_t h,uint8_t *src,uint8_t **dst,uint32_t *pdstsize) {
00679     phSCTX_to_RGBX_XBGR(w*h,3,4,1,0,src,dst,pdstsize);
00680 }
00681     
00682 /* ---------------------------------------------------------------------- */
00683 /* 1 byte swap B<->R
00684  * B G R
00685  * R G B
00686  *
00687  * This function works both ways. BGR->RGB and RGB->BGR
00688  * Conversion is done in place since the data size is the same.
00689  * ---------------------------------------------------------------------- */
00690 void phBGR24_x_RGB24(   uint32_t memsize, /* memory size in bytes */
00691                         uint8_t *data)
00692 {
00693     uint8_t *data_b = data;
00694     uint8_t *data_r = data + 2;
00695     uint32_t i = 0;
00696     uint32_t limit = memsize / 3;
00697   
00698     while (i < limit)
00699     {
00700         phXOR_SWAP(*data_b,*data_r);
00701         data_b += 3;
00702         data_r += 3;
00703         ++i;
00704     }
00705 }
00706 /* ---------------------------------------------------------------------- */
00707 /* 2 byte swaps B<->G A<->R
00708  * A B G R 
00709  * R G B A 
00710  *
00711  * This function works both ways. ABGR->RGBA and RGBA->AGBR
00712  * Conversion is done in place since the data size is the same.
00713  * ---------------------------------------------------------------------- */
00714 void phABGR32_x_RGBA32( uint32_t memsize, /* memory size in bytes */
00715                         uint8_t *data)
00716 {
00717     uint8_t *data_a = data;
00718     uint8_t *data_b = data_a + 1;
00719     uint8_t *data_g = data_b + 1;
00720     uint8_t *data_r = data_g + 1;
00721     uint32_t limit = memsize / 4;
00722     uint32_t i = 0;
00723     
00724     while (i < limit)
00725     {
00726         phXOR_SWAP(*data_b,*data_g);
00727         phXOR_SWAP(*data_r,*data_a);
00728         ++i;
00729         data_a += 4;
00730         data_b += 4;
00731         data_g += 4;
00732         data_r += 4;
00733     }
00734 }
00735 
00736 /* ---------------------------------------------------------------------- */
00737 /* 1 byte swap B<-->R
00738  * B G R A
00739  * R G B A 
00740  *
00741  * This function works both ways. BGRA->RGBA and RGBA->BGRA
00742  * Conversion is done in place since the data size is the same.
00743  * ---------------------------------------------------------------------- */
00744 void phBGRA32_x_RGBA32( uint32_t memsize, /* memory size in bytes */
00745                         uint8_t *data)
00746 {
00747     uint32_t a = 0;
00748     uint8_t *byte_one = (data);
00749     uint8_t *byte_two = (data + 2);
00750     
00751     for (a = 0; a < memsize; a += 4)
00752     {
00753         phXOR_SWAP(*byte_one,*byte_two);
00754         byte_one += 4; byte_two += 4;
00755     }
00756 }
00757 
00758 /* ---------------------------------------------------------------------- */
00759 /*  
00760  * B G R A
00761  * A B G R
00762  * ---------------------------------------------------------------------- */
00763 void phBGRA32_to_ABGR32( uint32_t memsize, /* memory size in bytes */
00764                          uint8_t *data)
00765 {
00766     uint32_t a = 0;
00767     uint8_t t = 0;
00768     
00769     for (a = 0; a < memsize; a += 4)
00770     {
00771         t = data[3];
00772         data[3] = data[2];
00773         data[2] = data[1];
00774         data[1] = data[0];
00775         data[0] = t;
00776         data+=4;
00777     }
00778 }
00779 /* ---------------------------------------------------------------------- */
00780 /*  
00781  * A B G R
00782  * B G R A
00783  * ---------------------------------------------------------------------- */
00784 void phABGR32_to_BGRA32( uint32_t memsize, /* memory size in bytes */
00785                          uint8_t *data)
00786 {
00787     uint32_t a = 0;
00788     uint8_t t = 0;
00789     
00790     for (a = 0; a < memsize; a += 4)
00791     {
00792         t = data[0];
00793         data[0] = data[1];
00794         data[1] = data[2];
00795         data[2] = data[3];
00796         data[3] = t;
00797         data+=4;
00798     }
00799 }
00800 /* ---------------------------------------------------------------------- */
00801 /* Copies from one byte depth to another byte depth */
00802 /* ---------------------------------------------------------------------- */
00803 void phVECTOR_BLOCK_COPY(   uint32_t nelems,
00804                             uint8_t elemsize,
00805                             uint8_t src_stride,
00806                             uint8_t dst_stride,
00807                             uint8_t block_size,
00808                             uint8_t src_index,
00809                             uint8_t dst_index,
00810                             uint8_t *src,
00811                             uint8_t **dst,
00812                             uint32_t *pdstsize )
00813 {
00814     uint32_t i = 0;
00815     uint32_t memsize = nelems * elemsize;
00816     uint32_t mem_limit = memsize - src_stride;
00817     uint8_t *ptr = NULL;
00818 
00819     if (pdstsize != NULL)
00820     {    
00821         phDALLOC_QUIET_VOIDRETURN((*dst),
00822                                     (*pdstsize),
00823                                     (nelems * dst_stride),
00824                                     uint8_t);
00825     }
00826     else
00827     {
00828         (*dst) = (uint8_t *)phCalloc(nelems * dst_stride,sizeof(uint8_t));
00829         if (*dst == NULL) return;
00830     }
00831     
00832     ptr = *dst;
00833 
00834     if (src_stride == 1)
00835     {
00836         /* src_index not used, it can only be 0 */
00837         for( i = 0; i < memsize; i++, src++, ptr += dst_stride )
00838             phMemset( &(ptr[dst_index]), src[0], block_size);
00839     }
00840     else if ((src_stride == dst_stride) && 
00841              (block_size == memsize))
00842     {
00843         phMemcpy(ptr,src,block_size);
00844     }
00845     else
00846     {
00847         for( i = 0; i < mem_limit; 
00848                             i += src_stride, 
00849                             src += src_stride, 
00850                             ptr += dst_stride )
00851         {
00852             phMemcpy( &(ptr[dst_index]),
00853                     &(src[src_index]),
00854                     block_size );
00855         }
00856     }
00857 }
00858 /* ---------------------------------------------------------------------- */
00859 /* This is very simple, the Y in YUV is the intensity value that is 
00860  * being calculated the rouchly the same way GREY8's luminance value 
00861  * is calculated.
00862  * So here we just copy the greyscale data into a piece of memory
00863  * that is the right size for YUV9 formatted data with the U and V set
00864  * to 0 by phCalloc */
00865 /* ---------------------------------------------------------------------- */
00866 void phGREY8_to_YUV9_ex(uint32_t w, 
00867                         uint32_t h,
00868                         uint8_t *src,
00869                         uint8_t **dst,
00870                         uint32_t *pdstsize )
00871 {
00872     uint32_t yuvsize = 0;
00873     
00874     yuvsize = phIMAGE_SIZE(w,h,phImageYUV9);    
00875 
00876     if (pdstsize != NULL)
00877     {
00878         phDALLOC_QUIET_VOIDRETURN((*dst),
00879                                     (*pdstsize),
00880                                     yuvsize,
00881                                     uint8_t);
00882     }
00883     else
00884     {
00885         (*dst) = (uint8_t *)phCalloc(yuvsize,sizeof(uint8_t));
00886         if (*dst == NULL) return;
00887     }
00888     phMemcpy(*dst,src,w*h);
00889 }
00890 
00891 /* ---------------------------------------------------------------------- */
00892 /* This uses averaging of the three color channels to convert the data 
00893  * from RGBX/XBGR to GREY SCALE (8 bits)
00894  *
00895  * X denotes 4 byte and 3 byte conformance. Meaning that both
00896  * RGB, RGBA (and vice versa) are both compatible.
00897  *
00898  * if *dst == NULL, this function failed
00899  * ---------------------------------------------------------------------- */
00900 void phRGBX_XBGR_to_GREY8_AVERAGE(  uint32_t nelems, /* elem count */
00901                                     uint8_t d, /* depth in bytes */
00902                                     uint8_t order, /* order - 0 RGBX; 1 XBGR */
00903                                     uint8_t offset,
00904                                     uint8_t *src,
00905                                     uint8_t **dst,
00906                                     uint32_t *pdstsize )
00907 {
00908     /*                  d == 4  1 : 0    d == 3   1 : 0  */
00909     /* int32_t ai = (3 + offset) % d; */
00910     int32_t bi = ((order ? 0 : 2) + offset) % d;
00911     int32_t gi = (1 + offset) % d;
00912     int32_t ri = ((order ? 2 : 0) + offset) % d;
00913     
00914     uint32_t i = 0;
00915     uint8_t *ptr = NULL;
00916     
00917     if (pdstsize != NULL)
00918     {
00919         phDALLOC_QUIET_VOIDRETURN((*dst),
00920                                     (*pdstsize),
00921                                     nelems,
00922                                     uint8_t);
00923     }
00924     else
00925     {
00926         (*dst) = (uint8_t *)phCalloc(nelems,sizeof(uint8_t));
00927         if (*dst == NULL) return;
00928     }
00929     
00930     ptr = *dst;
00931     
00932     for (i = 0; i < nelems; i++, ptr ++ , src += d)
00933         *ptr = (src[ri] + src[gi] + src[bi] / 3);
00934 }
00935 
00936 /* ---------------------------------------------------------------------- */
00937 /* This uses a luminance conversion to convert the data from RGBX/XBGR to
00938  * GREY SCALE (8 bits)
00939  *
00940  * X denotes 4 byte and 3 byte conformance. Meaning that both
00941  * RGB, RGBA (and vice versa) are both compatible.
00942  *
00943  * if *dst == NULL, this function failed
00944  * ---------------------------------------------------------------------- */
00945 void phRGBX_XBGR_to_GREY8_LUMINANCE(uint32_t nelems, /* elem count */
00946                                     uint8_t d, /* depth in bytes */
00947                                     uint8_t order, /* order - 0 RGBX; 1 XBGR */
00948                                     uint8_t offset,
00949                                     uint8_t *src,
00950                                     uint8_t **dst,
00951                                     uint32_t *pdstsize)
00952 {
00953     /*                  d == 4  1 : 0    d == 3   1 : 0  */
00954     /* int32_t ai = (3 + offset) % d; */
00955     int32_t bi = ((order ? 0 : 2) + offset) % d;
00956     int32_t gi = (1 + offset) % d;
00957     int32_t ri = ((order ? 2 : 0) + offset) % d;
00958     
00959     uint32_t i = 0;
00960     uint8_t *ptr = NULL;
00961     uint16_t Y = 0;
00962     
00963     if (pdstsize != NULL)
00964     {
00965         phDALLOC_QUIET_VOIDRETURN((*dst),
00966                                     (*pdstsize),
00967                                     nelems,
00968                                     uint8_t);
00969     }
00970     else
00971     {
00972         (*dst) = (uint8_t *)phCalloc(nelems,sizeof(uint8_t));
00973         if (*dst == NULL) return;
00974     }
00975     ptr = *dst;
00976     
00977     for( i = 0; i < nelems; i++, src += d, ptr++ )
00978     {
00979         Y = (uint16_t)((0.3 *  (*(src + ri))) + /* R */
00980                        (0.59 * (*(src + gi))) + /* G */
00981                        (0.11 * (*(src + bi))));  /* B */
00982                       
00983         if (Y > 255) Y = 255;
00984         *ptr = (uint8_t)Y;
00985     }
00986 }
00987 
00988 
00989 /* ----------------------------------------------------------------------------
00990  * The following YUV conversions were taken from CYUVImage.cpp, a class to 
00991  * convert to and from YUV9. This was coded by John R. Watson 
00992  * (jwatson@cs.uml.edu) for 91.549 Robotics II, Final Project on 12/18/03.
00993  *
00994  * They have been modified to be reusable in a C environment and 
00995  * adaptable within the phImage class.
00996  * ----------------------------------------------------------------------------
00997  */
00998 
00999 /* ----------------------------------------------------------------------------
01000  * phYUV9_to_RGBA32 -- convert a 9-bit YUV (4:1:0) image into 32-bit RGBA
01001  * ----------------------------------------------------------------------------
01002  * YUV9 is a 4:1:0 planar colorspace, with U and V components grouped in 4x4
01003  * blocks.  YUV9 is a 9 bits-per-pixel format
01004  * ------------------------------------------------------------------------- */
01005 void phYUV9_to_RGBX_XBGR(   uint32_t width,
01006                             uint32_t height,
01007                             uint8_t d,     /* d == 3 or 4 */
01008                             uint8_t order, /* order == 1:XBGR 0:RGBX */
01009                             uint8_t offset,
01010                             uint8_t *src,
01011                             uint8_t **dst,
01012                             uint32_t *pdstsize )
01013 {
01014     /* int32_t ai = (3 + offset) % d; */
01015     int32_t bi = ((order ? 0 : 2) + offset) % d;
01016     int32_t gi = (1 + offset) % d;
01017     int32_t ri = ((order ? 2 : 0) + offset) % d;
01018     
01019     uint8_t *yptr = NULL;
01020     uint8_t *uptr = NULL;
01021     uint8_t *vptr = NULL;
01022     int         stride  = 0;
01023     uint32_t    row     = 0;
01024     uint32_t    col     = 0;
01025     int idx = 0;
01026     int yy = 0;
01027     int uu = 0;
01028     int vv = 0;
01029     int r = 0;
01030     int g = 0;
01031     int b = 0;
01032 
01033     uint8_t *dptr = NULL;
01034 
01035     if (pdstsize != NULL)
01036     {
01037         phDALLOC_QUIET_VOIDRETURN((*dst),
01038                                     (*pdstsize),
01039                                     (width*height*d),
01040                                     uint8_t);
01041     }
01042     else
01043     {
01044         (*dst) = (uint8_t *)phCalloc(width*height*d,sizeof(uint8_t));
01045         if (*dst == NULL) return;
01046     }
01047     
01048     dptr = *dst;
01049     
01050     stride = width * height;
01051     yptr   = src;
01052     uptr   = yptr + stride;
01053     vptr   = uptr + (stride / 16);
01054     
01055     stride = width / 4;
01056     
01057     for (row=0; row < height; row++)
01058     {
01059         idx = 0;
01060 
01061         for (col=0; col < width; col++)
01062         {
01063             yy = (int)((*yptr++ + 16) * 1.164);
01064 
01065             /* we only have to do this once every 4 iterations */
01066             if ((col % 4) == 0)
01067             {
01068                 uu = uptr[idx] - 128;
01069                 vv = vptr[idx] - 128;
01070                 idx++;
01071             }
01072 
01073             /* R = (1.164 * (Y - 16)) + (1.596 * (V - 128)) */
01074             r = (int)(yy + (1.596 * vv));
01075 
01076             /* G = (1.164 * (Y - 16)) - (0.813 * (V - 128)) -
01077              *     (0.391 * (U - 128))
01078              */
01079             g = (int)(yy - (0.391 * uu) - (0.813 * vv));
01080 
01081             /* B = (1.164 * (Y - 16)) + (2.018 * (U - 128)) */
01082             b = (int)(yy + (2.018 * uu));
01083             
01084             dptr[ri] = phCLIP(r);
01085             dptr[gi] = phCLIP(g);
01086             dptr[bi] = phCLIP(b);
01087 
01088             /* this is the A part in our 32-bit RGBA image */
01089             /* pthoren - Calloc will init this to 0 anyway */
01090             /* dptr[ia] = 0; */
01091             dptr += d;
01092         }
01093 
01094         if ((row & 3) == 3)
01095         {
01096             uptr += stride;
01097             vptr += stride;
01098         }
01099     }
01100 }
01101 
01105 #if !phALLOW_OLD_MACROS
01106 typedef struct phPixel_u
01107 {
01108     int r;
01109     int g;
01110     int b;
01111     
01112     union {
01113         int b;
01114         int g;
01115         int r;
01116     } bgr;
01117     
01118     union {
01119         int v[3];
01120     } array;
01121     
01122 } phPixel;
01123 #endif
01124 
01125 
01126 /* ----------------------------------------------------------------------------
01127  * phRGBX_XBGR_to_YUV9 -- convert a 24-bit RGB image to 9-bit (4:1:0) YUV
01128  *
01129  * YUV 4:1:0 is a planar colorspace, with U and V components grouped in 4x4
01130  * blocks.  YUV9 is a 9-bits-per-pixel format.
01131  * ------------------------------------------------------------------------- */
01132 void phRGBX_XBGR_to_YUV9(   uint32_t width,
01133                             uint32_t height,
01134                             uint8_t d,     /* d == 3 or 4 */
01135                             uint8_t order, /* order == 1:XBGR 0:RGBX */
01136                             uint8_t offset,
01137                             uint8_t *src,
01138                             uint8_t **dst,
01139                             uint32_t *pdstsize)
01140 {
01141     /* int32_t ai = (3 + offset) % d; */
01142     int32_t bi = ((order ? 0 : 2) + offset) % d;
01143     int32_t gi = (1 + offset) % d;
01144     int32_t ri = ((order ? 2 : 0) + offset) % d;
01145     
01146     uint8_t *srcp = NULL;
01147     uint8_t *yptr = NULL;
01148     uint8_t *uptr = NULL;
01149     uint8_t *vptr = NULL;
01150     int         nblocks_w   = 0;
01151     int         stride      = 0;
01152     uint32_t    row         = 0;
01153     uint32_t    col         = 0;
01154     int r = 0;
01155     int g = 0;
01156     int b = 0;
01157     int i = 0;
01158     int j = 0;
01159     phPixel *blocks = NULL;
01160 
01161     uint32_t yuvsize = 0;
01162     
01163     yuvsize = phIMAGE_SIZE(width,height,phImageYUV9);    
01164 
01165     if (pdstsize != NULL)
01166     {
01167         phDALLOC_QUIET_VOIDRETURN((*dst),
01168                                     (*pdstsize),
01169                                     yuvsize,
01170                                     uint8_t);
01171     }
01172     else
01173     {
01174         (*dst) = (uint8_t *)phCalloc(yuvsize,sizeof(uint8_t));
01175         if (*dst == NULL) return;
01176     }
01177     
01178     blocks = (phPixel *)phCalloc(width / 4,sizeof(phPixel));
01179     if (blocks == NULL)
01180     {
01181         phFree(*dst);
01182         if (pdstsize != NULL) *pdstsize = 0;
01183         return;
01184     }
01185 
01186     /* number of U and V blocks along the width of the image */
01187     nblocks_w = width / 4;
01188 
01189     /* YUV is a planar format, so we use this stride value to find each
01190      * component
01191      */
01192     stride = width * height;
01193 
01194     srcp = src;
01195     yptr = *dst;
01196     uptr = yptr + stride;
01197     vptr = uptr + (stride / 16);
01198 
01199     /* Y computation is simple, because there is an intensity value for
01200      * every pixel in the image.  However, every 4x4 block of pixels share
01201      * a U and V value, so we must compute the mean of every 4x4 block in
01202      * the image and calculate U and V values from it.
01203      *
01204      * There are ((w * h) / 16) 4x4 blocks in an image.  Further, there
01205      * are (w / 4) blocks along the width of an image.  We work across the
01206      * image in strips, adding every set of 4 pixel values to one of the
01207      * (w / 4) blocks until we have done 4 rows.  Each of the (w / 4)
01208      * values is now a sum of the 16 pixels within its associated 4x4
01209      * block.  We compute the average of each value and then compute a U
01210      * and V value for each.
01211      */
01212     for (row=0; row < height; row++)
01213     {
01214         j = 0;
01215         for (col=0; col < width; col++)
01216         {
01217             r = srcp[ri];
01218             g = srcp[gi];
01219             b = srcp[bi];
01220         
01221             srcp += d;
01222             
01223             /* compute the Y (intensity) value */
01224             *yptr++ = (uint8_t)((0.257 * r) + (0.504 * g) +
01225                         (0.098 * b) + 16);
01226             
01227             /* defer computation of the U and V values */
01228             blocks[j].r += r;
01229             blocks[j].g += g;
01230             blocks[j].b += b;
01231 
01232             /* switch to the next 4 pixel block */
01233             if ((col & 3) == 3)
01234                 j++;
01235         }
01236 
01237         /* we've covered 4 rows, which means we now have data from
01238          * nblocks_w blocks.  Now, compute the U and V values for the
01239          * nblocks_w blocks
01240          */
01241         if ((row & 3) == 3)
01242         {
01243             for (i = 0; i < nblocks_w; i++)
01244             {
01245                 r = blocks[i].r / 16;
01246                 g = blocks[i].g / 16;
01247                 b = blocks[i].b / 16;
01248                 
01249                 *uptr++ = (uint8_t)(-(0.148 * r) - (0.291 * g)
01250                                    + (0.439 * b) + 128);
01251 
01252                 *vptr++ = (uint8_t)((0.439 * r) - (0.368 * g)
01253                             - (0.071 * b) + 128);
01254             }
01255             phMemset(blocks, 0, nblocks_w * sizeof(phPixel));
01256         }        
01257     }
01258     if (blocks)
01259     {
01260         free(blocks);
01261         blocks = NULL;
01262     }
01263 }
01264 /* ---------------------------------------------------------------------- */
01265 /* This uses a scaled HSV conversion to convert RGBX/XRGB to an
01266  * HSV representation stored in 24 bits/3 bytes to keep processing
01267  * algorithms simple and space consumption low.
01268  *
01269  * X denotes 4 byte and 3 byte conformance. Meaning that both
01270  * RGB, RGBA (and vice versa) are both compatible. Also,
01271  * 4 byte aligned HSV (HSV and HSVX) are also supported
01272  *
01273  * if *dst == NULL, this function failed
01274  *
01275  * HSV code was converted (and factored) from code found at:
01276  * http://www.mediamacros.com/item/item-1006687249/
01277  * 
01278  * ... using scale values from Meppelink's RGVtoHSV conversion code
01279  * available in the filter/packages/ directory.
01280  * ---------------------------------------------------------------------- */
01281 void phRGBX_XBGR_to_HSVX(   uint32_t nelems,
01282                             uint8_t id,
01283                             uint8_t od,
01284                             uint8_t order,
01285                             uint8_t offset,
01286                             uint8_t *src,
01287                             uint8_t **dst,
01288                             uint32_t *pdstsize )
01289 {
01290     uint32_t i = 0;
01291     uint8_t *ptr = NULL;
01292    
01293     int32_t copy_alpha = ((od > 3) && (id > 3) ? 1 : 0);
01294    
01295     float r = 0;
01296     float g = 0;
01297     float b = 0;
01298 
01299     int32_t ai = (3 + offset) % id;
01300     int32_t bi = ((order ? 0 : 2) + offset) % id;
01301     int32_t gi = (1 + offset) % id;
01302     int32_t ri = ((order ? 2 : 0) + offset) % id;
01303 
01304     const int32_t Hi = 0;
01305     const int32_t Si = 1;
01306     const int32_t Vi = 2;
01307     const int32_t Xi = 3;
01308     
01309     float       H = 0.0;
01310     float       S = 0.0;
01311     float       V = 0;
01312 
01313     float       min = 0;
01314     float       delta = 0.0;
01315     
01316     if (pdstsize != NULL)
01317     {
01318         phDALLOC_QUIET_VOIDRETURN((*dst),
01319                                     (*pdstsize),
01320                                     (nelems * 3),
01321                                     uint8_t);
01322     }
01323     else
01324     {
01325         (*dst) = (uint8_t *)phCalloc(nelems * 3,sizeof(uint8_t));
01326         if (*dst == NULL) return;
01327     }
01328     ptr = *dst;
01329 
01330     for (i = 0; i < nelems; i++, src += id, ptr += od)
01331     {
01332         r = (float)(src[ri] / 255.0);
01333         g = (float)(src[gi] / 255.0);
01334         b = (float)(src[bi] / 255.0);
01335         
01336         V   = phMAX3(r,g,b);
01337         min = phMIN3(r,g,b);
01338         delta = V - min;
01339 
01340         S = ((V == 0) ? 0.0f : 
01341                         (float)((float)delta / (float)V));
01342         
01343         if (S == 0.0) 
01344             H = 0.0;
01345         else
01346         {
01347             if (r == V)
01348                 /* between yellow and magenta */ 
01349                 H = ( g - b ) / delta;
01350             else if (g == V)
01351                 /* between cyan and yellow */
01352                 H = 2.0f + ((b - r) / delta);
01353             else
01354                 /* between magenta and cyan */
01355                 H = 4.0f + ((r - g) / delta);
01356             
01357             H *= 40.0f;
01358         }
01359         
01360         if (H < 0.0f) H += 240.0f; 
01361 
01362         ptr[Hi] = (uint8_t)phMIN(H,255.0f);
01363         ptr[Si] = (uint8_t)phMIN(S*255.0f,255.0f);
01364         ptr[Vi] = (uint8_t)phMIN(V*255.0f,255.0f);
01365         if (copy_alpha) ptr[Xi] = src[ai];
01366     }
01367 }
01368 
01369 /* ---------------------------------------------------------------------- */
01370 void phHSVX_to_RGBX_XBGR(   uint32_t nelems,
01371                             uint8_t id,
01372                             uint8_t od,
01373                             uint8_t order,
01374                             uint8_t offset,
01375                             uint8_t *src,
01376                             uint8_t **dst,
01377                             uint32_t *pdstsize)
01378 {
01379     uint32_t i = 0;
01380     uint8_t *ptr = NULL;
01381    
01382     int32_t copy_alpha = ((od > 3) && (id > 3) ? 1 : 0);
01383    
01384     int32_t ai = (3 + offset) % od;
01385     int32_t bi = ((order ? 0 : 2) + offset) % od;
01386     int32_t gi = (1 + offset) % od;
01387     int32_t ri = ((order ? 2 : 0) + offset) % od;
01388     
01389     const int32_t Hi = 0;
01390     const int32_t Si = 1;
01391     const int32_t Vi = 2;
01392     const int32_t Xi = 3;
01393     
01394     float       H = 0.0;
01395     float       S = 0.0;
01396     float       V = 0.0;
01397 
01398     float nearint = 0;
01399     float f = 0.0;
01400     float fp = 0;
01401     float fq = 0;
01402     float ft = 0;
01403     uint32_t ip = 0;
01404     uint32_t iq = 0;
01405     uint32_t it = 0;
01406     uint32_t iV = 0;
01407 
01408     if (pdstsize != NULL)
01409     {
01410         phDALLOC_QUIET_VOIDRETURN((*dst),
01411                                     (*pdstsize),
01412                                     (nelems * od),
01413                                     uint8_t);
01414     }
01415     else
01416     {
01417         (*dst) = (uint8_t *)phCalloc(nelems * od,sizeof(uint8_t));
01418         if (*dst == NULL) return;
01419     }
01420     
01421     ptr = *dst;
01422 
01423     for (i = 0; i < nelems; i++, src += id, ptr += od)
01424     {
01425         /* color is on black-and-white center line */
01426         if (src[Si] == 0)
01427         {
01428             ptr[ri] = ptr[gi] = ptr[bi] = src[Vi];
01429         }
01430         /* chromatic color */
01431         else
01432         {
01433             H = ((float)src[Hi] /  40.0f);
01434             S = ((float)src[Si] / 255.0f);
01435             V = ((float)src[Vi] / 255.0f);
01436             
01437             nearint = (float)floor(H);
01438             f = H - nearint;
01439             
01440             fp = V * (1.0f - S);
01441             fq = V * (1.0f - (S * f));
01442             ft = V * (1.0f - (S * (1.0f - f)));
01443             
01444             ip = (uint32_t)(fp * 255);
01445             iq = (uint32_t)(fq * 255);
01446             it = (uint32_t)(ft * 255);
01447             iV = (uint32_t)(V * 255.0f);
01448            
01449             nearint = (float)(((uint64_t)nearint) % 6);
01450             
01451             switch ((int32_t)nearint)
01452             {
01453                 case 0:
01454                     ptr[ri] = iV; ptr[gi] = it; ptr[bi] = ip;
01455                     break;
01456                 case 1:
01457                     ptr[ri] = iq; ptr[gi] = iV; ptr[bi] = ip;
01458                     break;
01459                 case 2:
01460                     ptr[ri] = ip; ptr[gi] = iV; ptr[bi] = it;
01461                     break;
01462                 case 3:
01463                     ptr[ri] = ip; ptr[gi] = iq; ptr[bi] = iV;
01464                     break;
01465                 case 4:
01466                     ptr[ri] = it; ptr[gi] = ip; ptr[bi] = iV;
01467                     break;
01468                 case 5:
01469                     ptr[ri] = iV; ptr[gi] = ip; ptr[bi] = iq;
01470                     break;
01471                 default:
01472                    fprintf(stderr,"Invalid nearint: %f\n",nearint);
01473                    fflush(stderr);
01474                    break;
01475             }
01476             if (copy_alpha) ptr[Xi] = src[ai];
01477         }
01478     }
01479 }
01480 
01481 /* ---------------------------------------------------------------------- *
01482  * This performs a conversion from an RGB space to SCT space.
01483  * The algorithm for RGB to SCT color space was found in 
01484  *      Computer Vision and Image Processing
01485  *          a practical approach using CVIPtools
01486  *       by Scott E Umbaugh
01487  *
01488  *  SCT or Spherical Coordinate Tranform has 3 bytes: L, A and B
01489  *      (Don't confuse B with b; B is the angle B and b is the blue of RGB)
01490  *  L = sqrt(R^2 + G^2 + B^2)
01491  *  A = cos^(-1)(B/L)
01492  *  B = cos^(-1)(R / (L sin (A)))
01493  *
01494  * Scaling is done on L, A and B to fit it into an 8 bit byte location.
01495  *  MAX(L) = sqrt(255*255 + 255*255 + 255*255) = 441.6729559
01496  *  MIN(L) = 0.0
01497  *  MAX(A) = MAX(B) = 1.0
01498  *  MIN(A) = MIN(B) = 0.0
01499  * ---------------------------------------------------------------------- */
01500 void phRGBX_XBGR_to_SCTX(   uint32_t nelems,
01501                             uint8_t id,
01502                             uint8_t od,
01503                             uint8_t order,
01504                             uint8_t offset,
01505                             uint8_t *src,
01506                             uint8_t **dst,
01507                             uint32_t *pdstsize )
01508 {
01509     uint32_t i = 0;
01510     uint8_t *ptr = NULL;
01511    
01512     int32_t copy_alpha = ((od > 3) && (id > 3) ? 1 : 0);
01513    
01514     float r = 0;
01515     float g = 0;
01516     float b = 0;
01517 
01518     int32_t ai = (3 + offset) % id;
01519     int32_t bi = ((order ? 0 : 2) + offset) % id;
01520     int32_t gi = (1 + offset) % id;
01521     int32_t ri = ((order ? 2 : 0) + offset) % id;
01522 
01523     const int32_t Li = 0;
01524     const int32_t Ai = 1;
01525     const int32_t Bi = 2;
01526     const int32_t Xi = 3;
01527     
01528     float       L = 0.0;
01529     float       A = 0.0;
01530     float       B = 0.0;
01531     float       t = 0.0f;
01532     /*
01533     uint32_t    intL = 0;
01534     uint32_t    intA = 0;
01535     uint32_t    intB = 0;
01536     */
01537     if (pdstsize != NULL)
01538     {
01539         phDALLOC_QUIET_VOIDRETURN((*dst),
01540                                     (*pdstsize),
01541                                     (nelems * 3),
01542                                     uint8_t);
01543     }
01544     else
01545     {
01546         (*dst) = (uint8_t *)phCalloc(nelems * 3,sizeof(uint8_t));
01547         if (*dst == NULL) return;
01548     }
01549     ptr = *dst;
01550 
01551     for (i = 0; i < nelems; i++, src += id, ptr += od)
01552     {
01553         r = ((float)src[ri]);
01554         g = ((float)src[gi]);
01555         b = ((float)src[bi]);
01556         
01557         L = sqrtf( r*r + b*b + g*g );
01558         if ((L == 0.0) || (L == -0.0))
01559         {
01560             A = B = acosf(0.0);
01561         }
01562         else
01563         {
01564             t = b / L;
01565             if (t <= -1.000000000f) t = -0.999999999f;
01566             if (t < 1.000000000f)   A = acosf( t );
01567             else                    A = 0.0f;
01568 
01569             t = r / (L * sinf(A) );
01570             if (t <= -1.000000000f) t = -0.999999999f;
01571             if (t < 1.000000000f)   B = acosf( t );
01572             else                    B = 0.0f;
01573         }
01574 #if 0
01575         fprintf(stderr,"r:%0.1f g:%0.1f b:%0.1f ",r,g,b);
01576         fprintf(stderr,"b/L:%0.8f sin(A):%0.8f r/(L*sin(A)):%0.8f ",
01577                 b/L,sinf(A),(r/(L*sinf(A))));
01578         fprintf(stderr,"L:%0.8f A:%0.8f B:%0.8f \n",
01579                 L,A,B );
01580 #endif  
01581         ptr[Li] = (uint8_t)((L / 441.6729559) * 255);
01582         ptr[Ai] = (uint8_t)(A * 255);
01583         ptr[Bi] = (uint8_t)(B * 255);
01584         if (copy_alpha) ptr[Xi] = src[ai];
01585 
01586 #if 0
01587         fprintf(stderr,"L/441..:%0.8f (L/441)*255:%0.8f ",
01588                 L/441.6729559,((L/441.6729559) * 255));
01589         fprintf(stderr,"A*255:%0.8f (uint)A*255:%d B*255:%0.8f (uint)B*255:%d \n",
01590                 A*255,(uint8_t)(A*255),B*255,(uint8_t)(B*255) );
01591         fprintf(stderr,"L:%d A:%d B:%d \n",
01592                 ptr[Li],ptr[Ai],ptr[Bi] );
01593 #endif
01594     }
01595 }
01596 
01597 /* ---------------------------------------------------------------------- */
01598 /* Conversion from SCT/LAB to RGB color space involves the reverse 
01599  * process from the above RGB->SCT conversion. The following is the 
01600  * order dependent series of equations to perform SCT->RGB:
01601  *
01602  *  b = L * cos(A)
01603  *  r = L * cos(B) * sin(A)
01604  *  g = sqrt( L^2 - ( r^2 + b^2 ) ) */
01605 /* ---------------------------------------------------------------------- */
01606 void phSCTX_to_RGBX_XBGR(   uint32_t nelems,
01607                             uint8_t id,
01608                             uint8_t od,
01609                             uint8_t order,
01610                             uint8_t offset,
01611                             uint8_t *src,
01612                             uint8_t **dst,
01613                             uint32_t *pdstsize)
01614 {
01615     uint32_t i = 0;
01616     uint8_t *ptr = NULL;
01617 
01618     int32_t copy_alpha = ((od > 3) && (id > 3) ? 1 : 0);
01619    
01620     int32_t ai = (3 + offset) % od;
01621     int32_t bi = ((order ? 0 : 2) + offset) % od;
01622     int32_t gi = (1 + offset) % od;
01623     int32_t ri = ((order ? 2 : 0) + offset) % od;
01624     
01625     float r = 0;
01626     float g = 0;
01627     float b = 0;
01628 
01629     const int32_t Li = 0;
01630     const int32_t Ai = 1;
01631     const int32_t Bi = 2;
01632     const int32_t Xi = 3;
01633     
01634     float       L = 0.0f;
01635     float       A = 0.0f;
01636     float       B = 0.0f;
01637     float       t = 0.0f;
01638 
01639     if (pdstsize != NULL)
01640     {
01641         phDALLOC_QUIET_VOIDRETURN((*dst),
01642                                     (*pdstsize),
01643                                     (nelems * od),
01644                                     uint8_t);
01645     }
01646     else
01647     {
01648         (*dst) = (uint8_t *)phCalloc(nelems * od,sizeof(uint8_t));
01649         if (*dst == NULL) return;
01650     }
01651     
01652     ptr = *dst;
01653 
01654     for (i = 0; i < nelems; i++, src += id, ptr += od)
01655     {
01656         L = (float)(((float)src[Li] / 255.0f)) * 441.6729559f;
01657         A = (float)(((float)src[Ai]) / 255.0f);
01658         B = (float)((float)src[Bi]) / 255.0f;
01659 #if 0
01660         fprintf(stderr,"L:%d A:%d B:%d ",src[Li],src[Ai],src[Bi]);
01661         fprintf(stderr,"L:%0.8f A:%0.8f B:%0.8f ",L,A,B);
01662 #endif
01663         
01664         /*  b = L * cos(A)                      */
01665         b = L * cosf(A);
01666         /*  r = L * cos(B) * sin(A)             */
01667         r = L * cosf(B) * sinf(A);
01668         /*  g = sqrt( L^2 - ( r^2 + b^2 ) )     */
01669         t = L*L - ( r*r + b*b );
01670         if (t < 0.0)
01671             g = 0.0f;
01672         else
01673             g = sqrtf(t);
01674 
01675 #if 0
01676         fprintf(stderr,"r:%0.8f g:%0.8f b:%0.8f ",r,g,b);
01677         fprintf(stderr,"r:%d g:%d b:%d\n",(uint8_t)r,(uint8_t)g,(uint8_t)b);
01678 #endif
01679         ptr[ri] = (uint8_t)r;
01680         ptr[gi] = (uint8_t)g;
01681         ptr[bi] = (uint8_t)b;
01682         if (copy_alpha) ptr[Xi] = src[ai];
01683     }
01684 }
01685 
01686 #ifdef __cplusplus
01687 }; /* extern "C" */
01688 #endif /* __cplusplus */




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4