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 |