ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

converter.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.