Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenconverter.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2009 Vincent Povirk 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 00021 #include <stdarg.h> 00022 00023 #define COBJMACROS 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "objbase.h" 00028 #include "wincodec.h" 00029 00030 #include "wincodecs_private.h" 00031 00032 #include "wine/debug.h" 00033 00034 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 00035 00036 struct FormatConverter; 00037 00038 enum pixelformat { 00039 format_1bppIndexed, 00040 format_2bppIndexed, 00041 format_4bppIndexed, 00042 format_8bppIndexed, 00043 format_BlackWhite, 00044 format_2bppGray, 00045 format_4bppGray, 00046 format_8bppGray, 00047 format_16bppGray, 00048 format_16bppBGR555, 00049 format_16bppBGR565, 00050 format_24bppBGR, 00051 format_32bppBGR, 00052 format_32bppBGRA, 00053 format_48bppRGB, 00054 format_64bppRGBA, 00055 }; 00056 00057 typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc, 00058 UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format); 00059 00060 struct pixelformatinfo { 00061 enum pixelformat format; 00062 const WICPixelFormatGUID *guid; 00063 copyfunc copy_function; 00064 }; 00065 00066 typedef struct FormatConverter { 00067 const IWICFormatConverterVtbl *lpVtbl; 00068 LONG ref; 00069 IWICBitmapSource *source; 00070 const struct pixelformatinfo *dst_format, *src_format; 00071 WICBitmapDitherType dither; 00072 double alpha_threshold; 00073 WICBitmapPaletteType palette_type; 00074 CRITICAL_SECTION lock; /* must be held when initialized */ 00075 } FormatConverter; 00076 00077 static void make_grayscale_palette(WICColor *colors, UINT num_colors) 00078 { 00079 int i, v; 00080 for (i=0; i<num_colors; i++) 00081 { 00082 v = i * 255 / (num_colors-1); 00083 colors[i] = 0xff000000 | v<<16 | v<<8 | v; 00084 } 00085 } 00086 00087 static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc, 00088 UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) 00089 { 00090 switch (source_format) 00091 { 00092 case format_1bppIndexed: 00093 case format_BlackWhite: 00094 if (prc) 00095 { 00096 HRESULT res; 00097 UINT x, y; 00098 BYTE *srcdata; 00099 UINT srcstride, srcdatasize; 00100 const BYTE *srcrow; 00101 const BYTE *srcbyte; 00102 BYTE *dstrow; 00103 DWORD *dstpixel; 00104 WICColor colors[2]; 00105 IWICPalette *palette; 00106 UINT actualcolors; 00107 00108 if (source_format == format_1bppIndexed) 00109 { 00110 res = PaletteImpl_Create(&palette); 00111 if (FAILED(res)) return res; 00112 00113 res = IWICBitmapSource_CopyPalette(This->source, palette); 00114 if (SUCCEEDED(res)) 00115 res = IWICPalette_GetColors(palette, 2, colors, &actualcolors); 00116 00117 IWICPalette_Release(palette); 00118 00119 if (FAILED(res)) return res; 00120 } 00121 else 00122 { 00123 colors[0] = 0xff000000; 00124 colors[1] = 0xffffffff; 00125 } 00126 00127 srcstride = (prc->Width+7)/8; 00128 srcdatasize = srcstride * prc->Height; 00129 00130 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00131 if (!srcdata) return E_OUTOFMEMORY; 00132 00133 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00134 00135 if (SUCCEEDED(res)) 00136 { 00137 srcrow = srcdata; 00138 dstrow = pbBuffer; 00139 for (y=0; y<prc->Height; y++) { 00140 srcbyte=(const BYTE*)srcrow; 00141 dstpixel=(DWORD*)dstrow; 00142 for (x=0; x<prc->Width; x+=8) { 00143 BYTE srcval; 00144 srcval=*srcbyte++; 00145 *dstpixel++ = colors[srcval>>7&1]; 00146 if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>6&1]; 00147 if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>5&1]; 00148 if (x+3 < prc->Width) *dstpixel++ = colors[srcval>>4&1]; 00149 if (x+4 < prc->Width) *dstpixel++ = colors[srcval>>3&1]; 00150 if (x+5 < prc->Width) *dstpixel++ = colors[srcval>>2&1]; 00151 if (x+6 < prc->Width) *dstpixel++ = colors[srcval>>1&1]; 00152 if (x+7 < prc->Width) *dstpixel++ = colors[srcval&1]; 00153 } 00154 srcrow += srcstride; 00155 dstrow += cbStride; 00156 } 00157 } 00158 00159 HeapFree(GetProcessHeap(), 0, srcdata); 00160 00161 return res; 00162 } 00163 return S_OK; 00164 case format_2bppIndexed: 00165 case format_2bppGray: 00166 if (prc) 00167 { 00168 HRESULT res; 00169 UINT x, y; 00170 BYTE *srcdata; 00171 UINT srcstride, srcdatasize; 00172 const BYTE *srcrow; 00173 const BYTE *srcbyte; 00174 BYTE *dstrow; 00175 DWORD *dstpixel; 00176 WICColor colors[4]; 00177 IWICPalette *palette; 00178 UINT actualcolors; 00179 00180 if (source_format == format_2bppIndexed) 00181 { 00182 res = PaletteImpl_Create(&palette); 00183 if (FAILED(res)) return res; 00184 00185 res = IWICBitmapSource_CopyPalette(This->source, palette); 00186 if (SUCCEEDED(res)) 00187 res = IWICPalette_GetColors(palette, 4, colors, &actualcolors); 00188 00189 IWICPalette_Release(palette); 00190 00191 if (FAILED(res)) return res; 00192 } 00193 else 00194 make_grayscale_palette(colors, 4); 00195 00196 srcstride = (prc->Width+3)/4; 00197 srcdatasize = srcstride * prc->Height; 00198 00199 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00200 if (!srcdata) return E_OUTOFMEMORY; 00201 00202 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00203 00204 if (SUCCEEDED(res)) 00205 { 00206 srcrow = srcdata; 00207 dstrow = pbBuffer; 00208 for (y=0; y<prc->Height; y++) { 00209 srcbyte=(const BYTE*)srcrow; 00210 dstpixel=(DWORD*)dstrow; 00211 for (x=0; x<prc->Width; x+=4) { 00212 BYTE srcval; 00213 srcval=*srcbyte++; 00214 *dstpixel++ = colors[srcval>>6]; 00215 if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>4&0x3]; 00216 if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>2&0x3]; 00217 if (x+1 < prc->Width) *dstpixel++ = colors[srcval&0x3]; 00218 } 00219 srcrow += srcstride; 00220 dstrow += cbStride; 00221 } 00222 } 00223 00224 HeapFree(GetProcessHeap(), 0, srcdata); 00225 00226 return res; 00227 } 00228 return S_OK; 00229 case format_4bppIndexed: 00230 case format_4bppGray: 00231 if (prc) 00232 { 00233 HRESULT res; 00234 UINT x, y; 00235 BYTE *srcdata; 00236 UINT srcstride, srcdatasize; 00237 const BYTE *srcrow; 00238 const BYTE *srcbyte; 00239 BYTE *dstrow; 00240 DWORD *dstpixel; 00241 WICColor colors[16]; 00242 IWICPalette *palette; 00243 UINT actualcolors; 00244 00245 if (source_format == format_4bppIndexed) 00246 { 00247 res = PaletteImpl_Create(&palette); 00248 if (FAILED(res)) return res; 00249 00250 res = IWICBitmapSource_CopyPalette(This->source, palette); 00251 if (SUCCEEDED(res)) 00252 res = IWICPalette_GetColors(palette, 16, colors, &actualcolors); 00253 00254 IWICPalette_Release(palette); 00255 00256 if (FAILED(res)) return res; 00257 } 00258 else 00259 make_grayscale_palette(colors, 16); 00260 00261 srcstride = (prc->Width+1)/2; 00262 srcdatasize = srcstride * prc->Height; 00263 00264 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00265 if (!srcdata) return E_OUTOFMEMORY; 00266 00267 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00268 00269 if (SUCCEEDED(res)) 00270 { 00271 srcrow = srcdata; 00272 dstrow = pbBuffer; 00273 for (y=0; y<prc->Height; y++) { 00274 srcbyte=(const BYTE*)srcrow; 00275 dstpixel=(DWORD*)dstrow; 00276 for (x=0; x<prc->Width; x+=2) { 00277 BYTE srcval; 00278 srcval=*srcbyte++; 00279 *dstpixel++ = colors[srcval>>4]; 00280 if (x+1 < prc->Width) *dstpixel++ = colors[srcval&0xf]; 00281 } 00282 srcrow += srcstride; 00283 dstrow += cbStride; 00284 } 00285 } 00286 00287 HeapFree(GetProcessHeap(), 0, srcdata); 00288 00289 return res; 00290 } 00291 return S_OK; 00292 case format_8bppGray: 00293 if (prc) 00294 { 00295 HRESULT res; 00296 UINT x, y; 00297 BYTE *srcdata; 00298 UINT srcstride, srcdatasize; 00299 const BYTE *srcrow; 00300 const BYTE *srcbyte; 00301 BYTE *dstrow; 00302 DWORD *dstpixel; 00303 00304 srcstride = prc->Width; 00305 srcdatasize = srcstride * prc->Height; 00306 00307 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00308 if (!srcdata) return E_OUTOFMEMORY; 00309 00310 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00311 00312 if (SUCCEEDED(res)) 00313 { 00314 srcrow = srcdata; 00315 dstrow = pbBuffer; 00316 for (y=0; y<prc->Height; y++) { 00317 srcbyte=(const BYTE*)srcrow; 00318 dstpixel=(DWORD*)dstrow; 00319 for (x=0; x<prc->Width; x++) 00320 { 00321 *dstpixel++ = 0xff000000|(*srcbyte<<16)|(*srcbyte<<8)|*srcbyte; 00322 srcbyte++; 00323 } 00324 srcrow += srcstride; 00325 dstrow += cbStride; 00326 } 00327 } 00328 00329 HeapFree(GetProcessHeap(), 0, srcdata); 00330 00331 return res; 00332 } 00333 return S_OK; 00334 case format_8bppIndexed: 00335 if (prc) 00336 { 00337 HRESULT res; 00338 UINT x, y; 00339 BYTE *srcdata; 00340 UINT srcstride, srcdatasize; 00341 const BYTE *srcrow; 00342 const BYTE *srcbyte; 00343 BYTE *dstrow; 00344 DWORD *dstpixel; 00345 WICColor colors[256]; 00346 IWICPalette *palette; 00347 UINT actualcolors; 00348 00349 res = PaletteImpl_Create(&palette); 00350 if (FAILED(res)) return res; 00351 00352 res = IWICBitmapSource_CopyPalette(This->source, palette); 00353 if (SUCCEEDED(res)) 00354 res = IWICPalette_GetColors(palette, 256, colors, &actualcolors); 00355 00356 IWICPalette_Release(palette); 00357 00358 if (FAILED(res)) return res; 00359 00360 srcstride = prc->Width; 00361 srcdatasize = srcstride * prc->Height; 00362 00363 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00364 if (!srcdata) return E_OUTOFMEMORY; 00365 00366 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00367 00368 if (SUCCEEDED(res)) 00369 { 00370 srcrow = srcdata; 00371 dstrow = pbBuffer; 00372 for (y=0; y<prc->Height; y++) { 00373 srcbyte=(const BYTE*)srcrow; 00374 dstpixel=(DWORD*)dstrow; 00375 for (x=0; x<prc->Width; x++) 00376 *dstpixel++ = colors[*srcbyte++]; 00377 srcrow += srcstride; 00378 dstrow += cbStride; 00379 } 00380 } 00381 00382 HeapFree(GetProcessHeap(), 0, srcdata); 00383 00384 return res; 00385 } 00386 return S_OK; 00387 case format_16bppGray: 00388 if (prc) 00389 { 00390 HRESULT res; 00391 UINT x, y; 00392 BYTE *srcdata; 00393 UINT srcstride, srcdatasize; 00394 const BYTE *srcrow; 00395 const BYTE *srcbyte; 00396 BYTE *dstrow; 00397 DWORD *dstpixel; 00398 00399 srcstride = prc->Width * 2; 00400 srcdatasize = srcstride * prc->Height; 00401 00402 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00403 if (!srcdata) return E_OUTOFMEMORY; 00404 00405 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00406 00407 if (SUCCEEDED(res)) 00408 { 00409 srcrow = srcdata; 00410 dstrow = pbBuffer; 00411 for (y=0; y<prc->Height; y++) { 00412 srcbyte=(const BYTE*)srcrow; 00413 dstpixel=(DWORD*)dstrow; 00414 for (x=0; x<prc->Width; x++) 00415 { 00416 *dstpixel++ = 0xff000000|(*srcbyte<<16)|(*srcbyte<<8)|*srcbyte; 00417 srcbyte+=2; 00418 } 00419 srcrow += srcstride; 00420 dstrow += cbStride; 00421 } 00422 } 00423 00424 HeapFree(GetProcessHeap(), 0, srcdata); 00425 00426 return res; 00427 } 00428 return S_OK; 00429 case format_16bppBGR555: 00430 if (prc) 00431 { 00432 HRESULT res; 00433 UINT x, y; 00434 BYTE *srcdata; 00435 UINT srcstride, srcdatasize; 00436 const BYTE *srcrow; 00437 const WORD *srcpixel; 00438 BYTE *dstrow; 00439 DWORD *dstpixel; 00440 00441 srcstride = 2 * prc->Width; 00442 srcdatasize = srcstride * prc->Height; 00443 00444 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00445 if (!srcdata) return E_OUTOFMEMORY; 00446 00447 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00448 00449 if (SUCCEEDED(res)) 00450 { 00451 srcrow = srcdata; 00452 dstrow = pbBuffer; 00453 for (y=0; y<prc->Height; y++) { 00454 srcpixel=(const WORD*)srcrow; 00455 dstpixel=(DWORD*)dstrow; 00456 for (x=0; x<prc->Width; x++) { 00457 WORD srcval; 00458 srcval=*srcpixel++; 00459 *dstpixel++=0xff000000 | /* constant 255 alpha */ 00460 ((srcval << 9) & 0xf80000) | /* r */ 00461 ((srcval << 4) & 0x070000) | /* r - 3 bits */ 00462 ((srcval << 6) & 0x00f800) | /* g */ 00463 ((srcval << 1) & 0x000700) | /* g - 3 bits */ 00464 ((srcval << 3) & 0x0000f8) | /* b */ 00465 ((srcval >> 2) & 0x000007); /* b - 3 bits */ 00466 } 00467 srcrow += srcstride; 00468 dstrow += cbStride; 00469 } 00470 } 00471 00472 HeapFree(GetProcessHeap(), 0, srcdata); 00473 00474 return res; 00475 } 00476 return S_OK; 00477 case format_16bppBGR565: 00478 if (prc) 00479 { 00480 HRESULT res; 00481 UINT x, y; 00482 BYTE *srcdata; 00483 UINT srcstride, srcdatasize; 00484 const BYTE *srcrow; 00485 const WORD *srcpixel; 00486 BYTE *dstrow; 00487 DWORD *dstpixel; 00488 00489 srcstride = 2 * prc->Width; 00490 srcdatasize = srcstride * prc->Height; 00491 00492 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00493 if (!srcdata) return E_OUTOFMEMORY; 00494 00495 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00496 00497 if (SUCCEEDED(res)) 00498 { 00499 srcrow = srcdata; 00500 dstrow = pbBuffer; 00501 for (y=0; y<prc->Height; y++) { 00502 srcpixel=(const WORD*)srcrow; 00503 dstpixel=(DWORD*)dstrow; 00504 for (x=0; x<prc->Width; x++) { 00505 WORD srcval; 00506 srcval=*srcpixel++; 00507 *dstpixel++=0xff000000 | /* constant 255 alpha */ 00508 ((srcval << 8) & 0xf80000) | /* r */ 00509 ((srcval << 3) & 0x070000) | /* r - 3 bits */ 00510 ((srcval << 5) & 0x00fc00) | /* g */ 00511 ((srcval >> 1) & 0x000300) | /* g - 2 bits */ 00512 ((srcval << 3) & 0x0000f8) | /* b */ 00513 ((srcval >> 2) & 0x000007); /* b - 3 bits */ 00514 } 00515 srcrow += srcstride; 00516 dstrow += cbStride; 00517 } 00518 } 00519 00520 HeapFree(GetProcessHeap(), 0, srcdata); 00521 00522 return res; 00523 } 00524 return S_OK; 00525 case format_24bppBGR: 00526 if (prc) 00527 { 00528 HRESULT res; 00529 UINT x, y; 00530 BYTE *srcdata; 00531 UINT srcstride, srcdatasize; 00532 const BYTE *srcrow; 00533 const BYTE *srcpixel; 00534 BYTE *dstrow; 00535 BYTE *dstpixel; 00536 00537 srcstride = 3 * prc->Width; 00538 srcdatasize = srcstride * prc->Height; 00539 00540 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00541 if (!srcdata) return E_OUTOFMEMORY; 00542 00543 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00544 00545 if (SUCCEEDED(res)) 00546 { 00547 srcrow = srcdata; 00548 dstrow = pbBuffer; 00549 for (y=0; y<prc->Height; y++) { 00550 srcpixel=srcrow; 00551 dstpixel=dstrow; 00552 for (x=0; x<prc->Width; x++) { 00553 *dstpixel++=*srcpixel++; /* blue */ 00554 *dstpixel++=*srcpixel++; /* green */ 00555 *dstpixel++=*srcpixel++; /* red */ 00556 *dstpixel++=255; /* alpha */ 00557 } 00558 srcrow += srcstride; 00559 dstrow += cbStride; 00560 } 00561 } 00562 00563 HeapFree(GetProcessHeap(), 0, srcdata); 00564 00565 return res; 00566 } 00567 return S_OK; 00568 case format_32bppBGR: 00569 if (prc) 00570 { 00571 HRESULT res; 00572 UINT x, y; 00573 00574 res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); 00575 if (FAILED(res)) return res; 00576 00577 /* set all alpha values to 255 */ 00578 for (y=0; y<prc->Height; y++) 00579 for (x=0; x<prc->Width; x++) 00580 pbBuffer[cbStride*y+4*x+3] = 0xff; 00581 } 00582 return S_OK; 00583 case format_32bppBGRA: 00584 if (prc) 00585 return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); 00586 return S_OK; 00587 case format_48bppRGB: 00588 if (prc) 00589 { 00590 HRESULT res; 00591 UINT x, y; 00592 BYTE *srcdata; 00593 UINT srcstride, srcdatasize; 00594 const BYTE *srcrow; 00595 const BYTE *srcpixel; 00596 BYTE *dstrow; 00597 DWORD *dstpixel; 00598 00599 srcstride = 6 * prc->Width; 00600 srcdatasize = srcstride * prc->Height; 00601 00602 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00603 if (!srcdata) return E_OUTOFMEMORY; 00604 00605 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00606 00607 if (SUCCEEDED(res)) 00608 { 00609 srcrow = srcdata; 00610 dstrow = pbBuffer; 00611 for (y=0; y<prc->Height; y++) { 00612 srcpixel=srcrow; 00613 dstpixel=(DWORD*)dstrow; 00614 for (x=0; x<prc->Width; x++) { 00615 BYTE red, green, blue; 00616 red = *srcpixel++; srcpixel++; 00617 green = *srcpixel++; srcpixel++; 00618 blue = *srcpixel++; srcpixel++; 00619 *dstpixel++=0xff000000|red<<16|green<<8|blue; 00620 } 00621 srcrow += srcstride; 00622 dstrow += cbStride; 00623 } 00624 } 00625 00626 HeapFree(GetProcessHeap(), 0, srcdata); 00627 00628 return res; 00629 } 00630 return S_OK; 00631 case format_64bppRGBA: 00632 if (prc) 00633 { 00634 HRESULT res; 00635 UINT x, y; 00636 BYTE *srcdata; 00637 UINT srcstride, srcdatasize; 00638 const BYTE *srcrow; 00639 const BYTE *srcpixel; 00640 BYTE *dstrow; 00641 DWORD *dstpixel; 00642 00643 srcstride = 8 * prc->Width; 00644 srcdatasize = srcstride * prc->Height; 00645 00646 srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); 00647 if (!srcdata) return E_OUTOFMEMORY; 00648 00649 res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); 00650 00651 if (SUCCEEDED(res)) 00652 { 00653 srcrow = srcdata; 00654 dstrow = pbBuffer; 00655 for (y=0; y<prc->Height; y++) { 00656 srcpixel=srcrow; 00657 dstpixel=(DWORD*)dstrow; 00658 for (x=0; x<prc->Width; x++) { 00659 BYTE red, green, blue, alpha; 00660 red = *srcpixel++; srcpixel++; 00661 green = *srcpixel++; srcpixel++; 00662 blue = *srcpixel++; srcpixel++; 00663 alpha = *srcpixel++; srcpixel++; 00664 *dstpixel++=alpha<<24|red<<16|green<<8|blue; 00665 } 00666 srcrow += srcstride; 00667 dstrow += cbStride; 00668 } 00669 } 00670 00671 HeapFree(GetProcessHeap(), 0, srcdata); 00672 00673 return res; 00674 } 00675 return S_OK; 00676 default: 00677 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00678 } 00679 } 00680 00681 static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc, 00682 UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) 00683 { 00684 switch (source_format) 00685 { 00686 case format_32bppBGR: 00687 case format_32bppBGRA: 00688 if (prc) 00689 return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); 00690 return S_OK; 00691 default: 00692 return copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format); 00693 } 00694 } 00695 00696 static const struct pixelformatinfo supported_formats[] = { 00697 {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL}, 00698 {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL}, 00699 {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL}, 00700 {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, NULL}, 00701 {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL}, 00702 {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL}, 00703 {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL}, 00704 {format_8bppGray, &GUID_WICPixelFormat8bppGray, NULL}, 00705 {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL}, 00706 {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL}, 00707 {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL}, 00708 {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, NULL}, 00709 {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR}, 00710 {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA}, 00711 {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL}, 00712 {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL}, 00713 {0} 00714 }; 00715 00716 static const struct pixelformatinfo *get_formatinfo(const WICPixelFormatGUID *format) 00717 { 00718 UINT i; 00719 00720 for (i=0; supported_formats[i].guid; i++) 00721 if (IsEqualGUID(supported_formats[i].guid, format)) return &supported_formats[i]; 00722 00723 return NULL; 00724 } 00725 00726 static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid, 00727 void **ppv) 00728 { 00729 FormatConverter *This = (FormatConverter*)iface; 00730 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00731 00732 if (!ppv) return E_INVALIDARG; 00733 00734 if (IsEqualIID(&IID_IUnknown, iid) || 00735 IsEqualIID(&IID_IWICBitmapSource, iid) || 00736 IsEqualIID(&IID_IWICFormatConverter, iid)) 00737 { 00738 *ppv = This; 00739 } 00740 else 00741 { 00742 *ppv = NULL; 00743 return E_NOINTERFACE; 00744 } 00745 00746 IUnknown_AddRef((IUnknown*)*ppv); 00747 return S_OK; 00748 } 00749 00750 static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface) 00751 { 00752 FormatConverter *This = (FormatConverter*)iface; 00753 ULONG ref = InterlockedIncrement(&This->ref); 00754 00755 TRACE("(%p) refcount=%u\n", iface, ref); 00756 00757 return ref; 00758 } 00759 00760 static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) 00761 { 00762 FormatConverter *This = (FormatConverter*)iface; 00763 ULONG ref = InterlockedDecrement(&This->ref); 00764 00765 TRACE("(%p) refcount=%u\n", iface, ref); 00766 00767 if (ref == 0) 00768 { 00769 This->lock.DebugInfo->Spare[0] = 0; 00770 DeleteCriticalSection(&This->lock); 00771 if (This->source) IWICBitmapSource_Release(This->source); 00772 HeapFree(GetProcessHeap(), 0, This); 00773 } 00774 00775 return ref; 00776 } 00777 00778 static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface, 00779 UINT *puiWidth, UINT *puiHeight) 00780 { 00781 FormatConverter *This = (FormatConverter*)iface; 00782 00783 TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight); 00784 00785 if (This->source) 00786 return IWICBitmapSource_GetSize(This->source, puiWidth, puiHeight); 00787 else 00788 return WINCODEC_ERR_NOTINITIALIZED; 00789 } 00790 00791 static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface, 00792 WICPixelFormatGUID *pPixelFormat) 00793 { 00794 FormatConverter *This = (FormatConverter*)iface; 00795 00796 TRACE("(%p,%p): stub\n", iface, pPixelFormat); 00797 00798 if (This->source) 00799 memcpy(pPixelFormat, This->dst_format->guid, sizeof(GUID)); 00800 else 00801 return WINCODEC_ERR_NOTINITIALIZED; 00802 00803 return S_OK; 00804 } 00805 00806 static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface, 00807 double *pDpiX, double *pDpiY) 00808 { 00809 FormatConverter *This = (FormatConverter*)iface; 00810 00811 TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY); 00812 00813 if (This->source) 00814 return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY); 00815 else 00816 return WINCODEC_ERR_NOTINITIALIZED; 00817 } 00818 00819 static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface, 00820 IWICPalette *pIPalette) 00821 { 00822 FIXME("(%p,%p): stub\n", iface, pIPalette); 00823 return E_NOTIMPL; 00824 } 00825 00826 static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface, 00827 const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) 00828 { 00829 FormatConverter *This = (FormatConverter*)iface; 00830 TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); 00831 00832 if (This->source) 00833 return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize, 00834 pbBuffer, This->src_format->format); 00835 else 00836 return WINCODEC_ERR_NOTINITIALIZED; 00837 } 00838 00839 static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, 00840 IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither, 00841 IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate) 00842 { 00843 FormatConverter *This = (FormatConverter*)iface; 00844 const struct pixelformatinfo *srcinfo, *dstinfo; 00845 static INT fixme=0; 00846 GUID srcFormat; 00847 HRESULT res=S_OK; 00848 00849 TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat), 00850 dither, pIPalette, alphaThresholdPercent, paletteTranslate); 00851 00852 if (pIPalette && !fixme++) FIXME("ignoring palette\n"); 00853 00854 EnterCriticalSection(&This->lock); 00855 00856 if (This->source) 00857 { 00858 res = WINCODEC_ERR_WRONGSTATE; 00859 goto end; 00860 } 00861 00862 res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat); 00863 if (FAILED(res)) goto end; 00864 00865 srcinfo = get_formatinfo(&srcFormat); 00866 if (!srcinfo) 00867 { 00868 res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; 00869 goto end; 00870 } 00871 00872 dstinfo = get_formatinfo(dstFormat); 00873 if (!dstinfo) 00874 { 00875 res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; 00876 goto end; 00877 } 00878 00879 if (dstinfo->copy_function) 00880 { 00881 IWICBitmapSource_AddRef(pISource); 00882 This->src_format = srcinfo; 00883 This->dst_format = dstinfo; 00884 This->dither = dither; 00885 This->alpha_threshold = alphaThresholdPercent; 00886 This->palette_type = paletteTranslate; 00887 This->source = pISource; 00888 } 00889 else 00890 res = WINCODEC_ERR_UNSUPPORTEDOPERATION; 00891 00892 end: 00893 00894 LeaveCriticalSection(&This->lock); 00895 00896 return res; 00897 } 00898 00899 static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface, 00900 REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat, 00901 BOOL *pfCanConvert) 00902 { 00903 FormatConverter *This = (FormatConverter*)iface; 00904 const struct pixelformatinfo *srcinfo, *dstinfo; 00905 00906 TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat), 00907 debugstr_guid(dstPixelFormat), pfCanConvert); 00908 00909 srcinfo = get_formatinfo(srcPixelFormat); 00910 if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; 00911 00912 dstinfo = get_formatinfo(dstPixelFormat); 00913 if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; 00914 00915 if (dstinfo->copy_function && 00916 SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format))) 00917 *pfCanConvert = TRUE; 00918 else 00919 *pfCanConvert = FALSE; 00920 00921 return S_OK; 00922 } 00923 00924 static const IWICFormatConverterVtbl FormatConverter_Vtbl = { 00925 FormatConverter_QueryInterface, 00926 FormatConverter_AddRef, 00927 FormatConverter_Release, 00928 FormatConverter_GetSize, 00929 FormatConverter_GetPixelFormat, 00930 FormatConverter_GetResolution, 00931 FormatConverter_CopyPalette, 00932 FormatConverter_CopyPixels, 00933 FormatConverter_Initialize, 00934 FormatConverter_CanConvert 00935 }; 00936 00937 HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) 00938 { 00939 FormatConverter *This; 00940 HRESULT ret; 00941 00942 TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv); 00943 00944 *ppv = NULL; 00945 00946 if (pUnkOuter) return CLASS_E_NOAGGREGATION; 00947 00948 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter)); 00949 if (!This) return E_OUTOFMEMORY; 00950 00951 This->lpVtbl = &FormatConverter_Vtbl; 00952 This->ref = 1; 00953 This->source = NULL; 00954 InitializeCriticalSection(&This->lock); 00955 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock"); 00956 00957 ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); 00958 IUnknown_Release((IUnknown*)This); 00959 00960 return ret; 00961 } Generated on Sat May 26 2012 04:25:24 for ReactOS by
1.7.6.1
|