ReactOS  0.4.14-dev-98-gb0d4763
converter.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009 Vincent Povirk
3  * Copyright 2016 Dmitry Timoshkov
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "config.h"
21 
22 #include <stdarg.h>
23 #include <math.h>
24 
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "objbase.h"
30 
31 #include "wincodecs_private.h"
32 
33 #include "wine/heap.h"
34 #include "wine/debug.h"
35 
37 
38 struct FormatConverter;
39 
65 };
66 
67 typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc,
68  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format);
69 
74 };
75 
76 typedef struct FormatConverter {
84  CRITICAL_SECTION lock; /* must be held when initialized */
86 
87 /* https://www.w3.org/Graphics/Color/srgb */
88 #ifndef __REACTOS__
89 static inline float from_sRGB_component(float f)
90 {
91  if (f <= 0.04045f) return f / 12.92f;
92  return powf((f + 0.055f) / 1.055f, 2.4f);
93 }
94 #endif
95 
96 static inline float to_sRGB_component(float f)
97 {
98  if (f <= 0.0031308f) return 12.92f * f;
99  return 1.055f * powf(f, 1.0f/2.4f) - 0.055f;
100 }
101 
102 #if 0 /* FIXME: enable once needed */
103 static void from_sRGB(BYTE *bgr)
104 {
105  float r, g, b;
106 
107  r = bgr[2] / 255.0f;
108  g = bgr[1] / 255.0f;
109  b = bgr[0] / 255.0f;
110 
114 
115  bgr[2] = (BYTE)(r * 255.0f);
116  bgr[1] = (BYTE)(g * 255.0f);
117  bgr[0] = (BYTE)(b * 255.0f);
118 }
119 
120 static void to_sRGB(BYTE *bgr)
121 {
122  float r, g, b;
123 
124  r = bgr[2] / 255.0f;
125  g = bgr[1] / 255.0f;
126  b = bgr[0] / 255.0f;
127 
128  r = to_sRGB_component(r);
129  g = to_sRGB_component(g);
130  b = to_sRGB_component(b);
131 
132  bgr[2] = (BYTE)(r * 255.0f);
133  bgr[1] = (BYTE)(g * 255.0f);
134  bgr[0] = (BYTE)(b * 255.0f);
135 }
136 #endif
137 
139 {
140  return CONTAINING_RECORD(iface, FormatConverter, IWICFormatConverter_iface);
141 }
142 
144  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
145 {
146  switch (source_format)
147  {
148  case format_1bppIndexed:
149  case format_BlackWhite:
150  if (prc)
151  {
152  HRESULT res;
153  INT x, y;
154  BYTE *srcdata;
155  UINT srcstride, srcdatasize;
156  const BYTE *srcrow;
157  const BYTE *srcbyte;
158  BYTE *dstrow;
159  DWORD *dstpixel;
160  WICColor colors[2];
162  UINT actualcolors;
163 
165  if (FAILED(res)) return res;
166 
167  if (source_format == format_1bppIndexed)
168  res = IWICBitmapSource_CopyPalette(This->source, palette);
169  else
170  res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedBW, FALSE);
171 
172  if (SUCCEEDED(res))
173  res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
174 
175  IWICPalette_Release(palette);
176  if (FAILED(res)) return res;
177 
178  srcstride = (prc->Width+7)/8;
179  srcdatasize = srcstride * prc->Height;
180 
181  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
182  if (!srcdata) return E_OUTOFMEMORY;
183 
184  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
185 
186  if (SUCCEEDED(res))
187  {
188  srcrow = srcdata;
189  dstrow = pbBuffer;
190  for (y=0; y<prc->Height; y++) {
191  srcbyte = srcrow;
192  dstpixel=(DWORD*)dstrow;
193  for (x=0; x<prc->Width; x+=8) {
194  BYTE srcval;
195  srcval=*srcbyte++;
196  *dstpixel++ = colors[srcval>>7&1];
197  if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>6&1];
198  if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>5&1];
199  if (x+3 < prc->Width) *dstpixel++ = colors[srcval>>4&1];
200  if (x+4 < prc->Width) *dstpixel++ = colors[srcval>>3&1];
201  if (x+5 < prc->Width) *dstpixel++ = colors[srcval>>2&1];
202  if (x+6 < prc->Width) *dstpixel++ = colors[srcval>>1&1];
203  if (x+7 < prc->Width) *dstpixel++ = colors[srcval&1];
204  }
205  srcrow += srcstride;
206  dstrow += cbStride;
207  }
208  }
209 
210  HeapFree(GetProcessHeap(), 0, srcdata);
211 
212  return res;
213  }
214  return S_OK;
215  case format_2bppIndexed:
216  case format_2bppGray:
217  if (prc)
218  {
219  HRESULT res;
220  INT x, y;
221  BYTE *srcdata;
222  UINT srcstride, srcdatasize;
223  const BYTE *srcrow;
224  const BYTE *srcbyte;
225  BYTE *dstrow;
226  DWORD *dstpixel;
227  WICColor colors[4];
229  UINT actualcolors;
230 
232  if (FAILED(res)) return res;
233 
234  if (source_format == format_2bppIndexed)
235  res = IWICBitmapSource_CopyPalette(This->source, palette);
236  else
237  res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
238 
239  if (SUCCEEDED(res))
240  res = IWICPalette_GetColors(palette, 4, colors, &actualcolors);
241 
242  IWICPalette_Release(palette);
243  if (FAILED(res)) return res;
244 
245  srcstride = (prc->Width+3)/4;
246  srcdatasize = srcstride * prc->Height;
247 
248  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
249  if (!srcdata) return E_OUTOFMEMORY;
250 
251  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
252 
253  if (SUCCEEDED(res))
254  {
255  srcrow = srcdata;
256  dstrow = pbBuffer;
257  for (y=0; y<prc->Height; y++) {
258  srcbyte = srcrow;
259  dstpixel=(DWORD*)dstrow;
260  for (x=0; x<prc->Width; x+=4) {
261  BYTE srcval;
262  srcval=*srcbyte++;
263  *dstpixel++ = colors[srcval>>6];
264  if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>4&0x3];
265  if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>2&0x3];
266  if (x+3 < prc->Width) *dstpixel++ = colors[srcval&0x3];
267  }
268  srcrow += srcstride;
269  dstrow += cbStride;
270  }
271  }
272 
273  HeapFree(GetProcessHeap(), 0, srcdata);
274 
275  return res;
276  }
277  return S_OK;
278  case format_4bppIndexed:
279  case format_4bppGray:
280  if (prc)
281  {
282  HRESULT res;
283  INT x, y;
284  BYTE *srcdata;
285  UINT srcstride, srcdatasize;
286  const BYTE *srcrow;
287  const BYTE *srcbyte;
288  BYTE *dstrow;
289  DWORD *dstpixel;
290  WICColor colors[16];
292  UINT actualcolors;
293 
295  if (FAILED(res)) return res;
296 
297  if (source_format == format_4bppIndexed)
298  res = IWICBitmapSource_CopyPalette(This->source, palette);
299  else
300  res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray16, FALSE);
301 
302  if (SUCCEEDED(res))
303  res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
304 
305  IWICPalette_Release(palette);
306  if (FAILED(res)) return res;
307 
308  srcstride = (prc->Width+1)/2;
309  srcdatasize = srcstride * prc->Height;
310 
311  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
312  if (!srcdata) return E_OUTOFMEMORY;
313 
314  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
315 
316  if (SUCCEEDED(res))
317  {
318  srcrow = srcdata;
319  dstrow = pbBuffer;
320  for (y=0; y<prc->Height; y++) {
321  srcbyte = srcrow;
322  dstpixel=(DWORD*)dstrow;
323  for (x=0; x<prc->Width; x+=2) {
324  BYTE srcval;
325  srcval=*srcbyte++;
326  *dstpixel++ = colors[srcval>>4];
327  if (x+1 < prc->Width) *dstpixel++ = colors[srcval&0xf];
328  }
329  srcrow += srcstride;
330  dstrow += cbStride;
331  }
332  }
333 
334  HeapFree(GetProcessHeap(), 0, srcdata);
335 
336  return res;
337  }
338  return S_OK;
339  case format_8bppGray:
340  if (prc)
341  {
342  HRESULT res;
343  INT x, y;
344  BYTE *srcdata;
345  UINT srcstride, srcdatasize;
346  const BYTE *srcrow;
347  const BYTE *srcbyte;
348  BYTE *dstrow;
349  DWORD *dstpixel;
350 
351  srcstride = prc->Width;
352  srcdatasize = srcstride * prc->Height;
353 
354  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
355  if (!srcdata) return E_OUTOFMEMORY;
356 
357  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
358 
359  if (SUCCEEDED(res))
360  {
361  srcrow = srcdata;
362  dstrow = pbBuffer;
363  for (y=0; y<prc->Height; y++) {
364  srcbyte = srcrow;
365  dstpixel=(DWORD*)dstrow;
366  for (x=0; x<prc->Width; x++)
367  {
368  *dstpixel++ = 0xff000000|(*srcbyte<<16)|(*srcbyte<<8)|*srcbyte;
369  srcbyte++;
370  }
371  srcrow += srcstride;
372  dstrow += cbStride;
373  }
374  }
375 
376  HeapFree(GetProcessHeap(), 0, srcdata);
377 
378  return res;
379  }
380  return S_OK;
381  case format_8bppIndexed:
382  if (prc)
383  {
384  HRESULT res;
385  INT x, y;
386  BYTE *srcdata;
387  UINT srcstride, srcdatasize;
388  const BYTE *srcrow;
389  const BYTE *srcbyte;
390  BYTE *dstrow;
391  DWORD *dstpixel;
392  WICColor colors[256];
394  UINT actualcolors;
395 
397  if (FAILED(res)) return res;
398 
399  res = IWICBitmapSource_CopyPalette(This->source, palette);
400  if (SUCCEEDED(res))
401  res = IWICPalette_GetColors(palette, 256, colors, &actualcolors);
402 
403  IWICPalette_Release(palette);
404 
405  if (FAILED(res)) return res;
406 
407  srcstride = prc->Width;
408  srcdatasize = srcstride * prc->Height;
409 
410  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
411  if (!srcdata) return E_OUTOFMEMORY;
412 
413  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
414 
415  if (SUCCEEDED(res))
416  {
417  srcrow = srcdata;
418  dstrow = pbBuffer;
419  for (y=0; y<prc->Height; y++) {
420  srcbyte = srcrow;
421  dstpixel=(DWORD*)dstrow;
422  for (x=0; x<prc->Width; x++)
423  *dstpixel++ = colors[*srcbyte++];
424  srcrow += srcstride;
425  dstrow += cbStride;
426  }
427  }
428 
429  HeapFree(GetProcessHeap(), 0, srcdata);
430 
431  return res;
432  }
433  return S_OK;
434  case format_16bppGray:
435  if (prc)
436  {
437  HRESULT res;
438  INT x, y;
439  BYTE *srcdata;
440  UINT srcstride, srcdatasize;
441  const BYTE *srcrow;
442  const BYTE *srcbyte;
443  BYTE *dstrow;
444  DWORD *dstpixel;
445 
446  srcstride = prc->Width * 2;
447  srcdatasize = srcstride * prc->Height;
448 
449  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
450  if (!srcdata) return E_OUTOFMEMORY;
451 
452  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
453 
454  if (SUCCEEDED(res))
455  {
456  srcrow = srcdata;
457  dstrow = pbBuffer;
458  for (y=0; y<prc->Height; y++) {
459  srcbyte = srcrow;
460  dstpixel=(DWORD*)dstrow;
461  for (x=0; x<prc->Width; x++)
462  {
463  *dstpixel++ = 0xff000000|(*srcbyte<<16)|(*srcbyte<<8)|*srcbyte;
464  srcbyte+=2;
465  }
466  srcrow += srcstride;
467  dstrow += cbStride;
468  }
469  }
470 
471  HeapFree(GetProcessHeap(), 0, srcdata);
472 
473  return res;
474  }
475  return S_OK;
476  case format_16bppBGR555:
477  if (prc)
478  {
479  HRESULT res;
480  INT x, y;
481  BYTE *srcdata;
482  UINT srcstride, srcdatasize;
483  const BYTE *srcrow;
484  const WORD *srcpixel;
485  BYTE *dstrow;
486  DWORD *dstpixel;
487 
488  srcstride = 2 * prc->Width;
489  srcdatasize = srcstride * prc->Height;
490 
491  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
492  if (!srcdata) return E_OUTOFMEMORY;
493 
494  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
495 
496  if (SUCCEEDED(res))
497  {
498  srcrow = srcdata;
499  dstrow = pbBuffer;
500  for (y=0; y<prc->Height; y++) {
501  srcpixel=(const WORD*)srcrow;
502  dstpixel=(DWORD*)dstrow;
503  for (x=0; x<prc->Width; x++) {
504  WORD srcval;
505  srcval=*srcpixel++;
506  *dstpixel++=0xff000000 | /* constant 255 alpha */
507  ((srcval << 9) & 0xf80000) | /* r */
508  ((srcval << 4) & 0x070000) | /* r - 3 bits */
509  ((srcval << 6) & 0x00f800) | /* g */
510  ((srcval << 1) & 0x000700) | /* g - 3 bits */
511  ((srcval << 3) & 0x0000f8) | /* b */
512  ((srcval >> 2) & 0x000007); /* b - 3 bits */
513  }
514  srcrow += srcstride;
515  dstrow += cbStride;
516  }
517  }
518 
519  HeapFree(GetProcessHeap(), 0, srcdata);
520 
521  return res;
522  }
523  return S_OK;
524  case format_16bppBGR565:
525  if (prc)
526  {
527  HRESULT res;
528  INT x, y;
529  BYTE *srcdata;
530  UINT srcstride, srcdatasize;
531  const BYTE *srcrow;
532  const WORD *srcpixel;
533  BYTE *dstrow;
534  DWORD *dstpixel;
535 
536  srcstride = 2 * prc->Width;
537  srcdatasize = srcstride * prc->Height;
538 
539  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
540  if (!srcdata) return E_OUTOFMEMORY;
541 
542  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
543 
544  if (SUCCEEDED(res))
545  {
546  srcrow = srcdata;
547  dstrow = pbBuffer;
548  for (y=0; y<prc->Height; y++) {
549  srcpixel=(const WORD*)srcrow;
550  dstpixel=(DWORD*)dstrow;
551  for (x=0; x<prc->Width; x++) {
552  WORD srcval;
553  srcval=*srcpixel++;
554  *dstpixel++=0xff000000 | /* constant 255 alpha */
555  ((srcval << 8) & 0xf80000) | /* r */
556  ((srcval << 3) & 0x070000) | /* r - 3 bits */
557  ((srcval << 5) & 0x00fc00) | /* g */
558  ((srcval >> 1) & 0x000300) | /* g - 2 bits */
559  ((srcval << 3) & 0x0000f8) | /* b */
560  ((srcval >> 2) & 0x000007); /* b - 3 bits */
561  }
562  srcrow += srcstride;
563  dstrow += cbStride;
564  }
565  }
566 
567  HeapFree(GetProcessHeap(), 0, srcdata);
568 
569  return res;
570  }
571  return S_OK;
573  if (prc)
574  {
575  HRESULT res;
576  INT x, y;
577  BYTE *srcdata;
578  UINT srcstride, srcdatasize;
579  const BYTE *srcrow;
580  const WORD *srcpixel;
581  BYTE *dstrow;
582  DWORD *dstpixel;
583 
584  srcstride = 2 * prc->Width;
585  srcdatasize = srcstride * prc->Height;
586 
587  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
588  if (!srcdata) return E_OUTOFMEMORY;
589 
590  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
591 
592  if (SUCCEEDED(res))
593  {
594  srcrow = srcdata;
595  dstrow = pbBuffer;
596  for (y=0; y<prc->Height; y++) {
597  srcpixel=(const WORD*)srcrow;
598  dstpixel=(DWORD*)dstrow;
599  for (x=0; x<prc->Width; x++) {
600  WORD srcval;
601  srcval=*srcpixel++;
602  *dstpixel++=((srcval & 0x8000) ? 0xff000000 : 0) | /* alpha */
603  ((srcval << 9) & 0xf80000) | /* r */
604  ((srcval << 4) & 0x070000) | /* r - 3 bits */
605  ((srcval << 6) & 0x00f800) | /* g */
606  ((srcval << 1) & 0x000700) | /* g - 3 bits */
607  ((srcval << 3) & 0x0000f8) | /* b */
608  ((srcval >> 2) & 0x000007); /* b - 3 bits */
609  }
610  srcrow += srcstride;
611  dstrow += cbStride;
612  }
613  }
614 
615  HeapFree(GetProcessHeap(), 0, srcdata);
616 
617  return res;
618  }
619  return S_OK;
620  case format_24bppBGR:
621  if (prc)
622  {
623  HRESULT res;
624  INT x, y;
625  BYTE *srcdata;
626  UINT srcstride, srcdatasize;
627  const BYTE *srcrow;
628  const BYTE *srcpixel;
629  BYTE *dstrow;
630  BYTE *dstpixel;
631 
632  srcstride = 3 * prc->Width;
633  srcdatasize = srcstride * prc->Height;
634 
635  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
636  if (!srcdata) return E_OUTOFMEMORY;
637 
638  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
639 
640  if (SUCCEEDED(res))
641  {
642  srcrow = srcdata;
643  dstrow = pbBuffer;
644  for (y=0; y<prc->Height; y++) {
645  srcpixel=srcrow;
646  dstpixel=dstrow;
647  for (x=0; x<prc->Width; x++) {
648  *dstpixel++=*srcpixel++; /* blue */
649  *dstpixel++=*srcpixel++; /* green */
650  *dstpixel++=*srcpixel++; /* red */
651  *dstpixel++=255; /* alpha */
652  }
653  srcrow += srcstride;
654  dstrow += cbStride;
655  }
656  }
657 
658  HeapFree(GetProcessHeap(), 0, srcdata);
659 
660  return res;
661  }
662  return S_OK;
663  case format_24bppRGB:
664  if (prc)
665  {
666  HRESULT res;
667  INT x, y;
668  BYTE *srcdata;
669  UINT srcstride, srcdatasize;
670  const BYTE *srcrow;
671  const BYTE *srcpixel;
672  BYTE *dstrow;
673  BYTE *dstpixel;
674  BYTE tmppixel[3];
675 
676  srcstride = 3 * prc->Width;
677  srcdatasize = srcstride * prc->Height;
678 
679  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
680  if (!srcdata) return E_OUTOFMEMORY;
681 
682  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
683 
684  if (SUCCEEDED(res))
685  {
686  srcrow = srcdata;
687  dstrow = pbBuffer;
688  for (y=0; y<prc->Height; y++) {
689  srcpixel=srcrow;
690  dstpixel=dstrow;
691  for (x=0; x<prc->Width; x++) {
692  tmppixel[0]=*srcpixel++; /* red */
693  tmppixel[1]=*srcpixel++; /* green */
694  tmppixel[2]=*srcpixel++; /* blue */
695 
696  *dstpixel++=tmppixel[2]; /* blue */
697  *dstpixel++=tmppixel[1]; /* green */
698  *dstpixel++=tmppixel[0]; /* red */
699  *dstpixel++=255; /* alpha */
700  }
701  srcrow += srcstride;
702  dstrow += cbStride;
703  }
704  }
705 
706  HeapFree(GetProcessHeap(), 0, srcdata);
707 
708  return res;
709  }
710  return S_OK;
711  case format_32bppBGR:
712  if (prc)
713  {
714  HRESULT res;
715  INT x, y;
716 
717  res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
718  if (FAILED(res)) return res;
719 
720  /* set all alpha values to 255 */
721  for (y=0; y<prc->Height; y++)
722  for (x=0; x<prc->Width; x++)
723  pbBuffer[cbStride*y+4*x+3] = 0xff;
724  }
725  return S_OK;
726  case format_32bppBGRA:
727  if (prc)
728  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
729  return S_OK;
730  case format_32bppPBGRA:
731  if (prc)
732  {
733  HRESULT res;
734  INT x, y;
735 
736  res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
737  if (FAILED(res)) return res;
738 
739  for (y=0; y<prc->Height; y++)
740  for (x=0; x<prc->Width; x++)
741  {
742  BYTE alpha = pbBuffer[cbStride*y+4*x+3];
743  if (alpha != 0 && alpha != 255)
744  {
745  pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * 255 / alpha;
746  pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * 255 / alpha;
747  pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * 255 / alpha;
748  }
749  }
750  }
751  return S_OK;
752  case format_48bppRGB:
753  if (prc)
754  {
755  HRESULT res;
756  INT x, y;
757  BYTE *srcdata;
758  UINT srcstride, srcdatasize;
759  const BYTE *srcrow;
760  const BYTE *srcpixel;
761  BYTE *dstrow;
762  DWORD *dstpixel;
763 
764  srcstride = 6 * prc->Width;
765  srcdatasize = srcstride * prc->Height;
766 
767  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
768  if (!srcdata) return E_OUTOFMEMORY;
769 
770  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
771 
772  if (SUCCEEDED(res))
773  {
774  srcrow = srcdata;
775  dstrow = pbBuffer;
776  for (y=0; y<prc->Height; y++) {
777  srcpixel=srcrow;
778  dstpixel=(DWORD*)dstrow;
779  for (x=0; x<prc->Width; x++) {
780  BYTE red, green, blue;
781  red = *srcpixel++; srcpixel++;
782  green = *srcpixel++; srcpixel++;
783  blue = *srcpixel++; srcpixel++;
784  *dstpixel++=0xff000000|red<<16|green<<8|blue;
785  }
786  srcrow += srcstride;
787  dstrow += cbStride;
788  }
789  }
790 
791  HeapFree(GetProcessHeap(), 0, srcdata);
792 
793  return res;
794  }
795  return S_OK;
796  case format_64bppRGBA:
797  if (prc)
798  {
799  HRESULT res;
800  INT x, y;
801  BYTE *srcdata;
802  UINT srcstride, srcdatasize;
803  const BYTE *srcrow;
804  const BYTE *srcpixel;
805  BYTE *dstrow;
806  DWORD *dstpixel;
807 
808  srcstride = 8 * prc->Width;
809  srcdatasize = srcstride * prc->Height;
810 
811  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
812  if (!srcdata) return E_OUTOFMEMORY;
813 
814  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
815 
816  if (SUCCEEDED(res))
817  {
818  srcrow = srcdata;
819  dstrow = pbBuffer;
820  for (y=0; y<prc->Height; y++) {
821  srcpixel=srcrow;
822  dstpixel=(DWORD*)dstrow;
823  for (x=0; x<prc->Width; x++) {
824  BYTE red, green, blue, alpha;
825  red = *srcpixel++; srcpixel++;
826  green = *srcpixel++; srcpixel++;
827  blue = *srcpixel++; srcpixel++;
828  alpha = *srcpixel++; srcpixel++;
829  *dstpixel++=alpha<<24|red<<16|green<<8|blue;
830  }
831  srcrow += srcstride;
832  dstrow += cbStride;
833  }
834  }
835 
836  HeapFree(GetProcessHeap(), 0, srcdata);
837 
838  return res;
839  }
840  return S_OK;
841  case format_32bppCMYK:
842  if (prc)
843  {
844  HRESULT res;
845  UINT x, y;
846 
847  res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
848  if (FAILED(res)) return res;
849 
850  for (y=0; y<prc->Height; y++)
851  for (x=0; x<prc->Width; x++)
852  {
853  BYTE *pixel = pbBuffer+cbStride*y+4*x;
854  BYTE c=pixel[0], m=pixel[1], y=pixel[2], k=pixel[3];
855  pixel[0] = (255-y)*(255-k)/255; /* blue */
856  pixel[1] = (255-m)*(255-k)/255; /* green */
857  pixel[2] = (255-c)*(255-k)/255; /* red */
858  pixel[3] = 255; /* alpha */
859  }
860  }
861  return S_OK;
862  default:
864  }
865 }
866 
868  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
869 {
870  HRESULT hr;
871 
872  switch (source_format)
873  {
874  case format_32bppRGB:
875  case format_32bppRGBA:
876  case format_32bppPRGBA:
877  if (prc)
878  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
879  return S_OK;
880  default:
881  hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
882  if (SUCCEEDED(hr) && prc)
883  reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride);
884  return hr;
885  }
886 }
887 
889  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
890 {
891  switch (source_format)
892  {
893  case format_32bppBGR:
894  case format_32bppBGRA:
895  case format_32bppPBGRA:
896  if (prc)
897  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
898  return S_OK;
899  default:
900  return copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
901  }
902 }
903 
905  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
906 {
907  switch (source_format)
908  {
909  case format_32bppRGB:
910  case format_32bppRGBA:
911  case format_32bppPRGBA:
912  if (prc)
913  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
914  return S_OK;
915  default:
916  return copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
917  }
918 }
919 
921  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
922 {
923  HRESULT hr;
924 
925  switch (source_format)
926  {
927  case format_32bppPBGRA:
928  if (prc)
929  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
930  return S_OK;
931  default:
932  hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
933  if (SUCCEEDED(hr) && prc)
934  {
935  INT x, y;
936 
937  for (y=0; y<prc->Height; y++)
938  for (x=0; x<prc->Width; x++)
939  {
940  BYTE alpha = pbBuffer[cbStride*y+4*x+3];
941  if (alpha != 255)
942  {
943  pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255;
944  pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255;
945  pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255;
946  }
947  }
948  }
949  return hr;
950  }
951 }
952 
954  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
955 {
956  HRESULT hr;
957 
958  switch (source_format)
959  {
960  case format_32bppPRGBA:
961  if (prc)
962  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
963  return S_OK;
964  default:
965  hr = copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
966  if (SUCCEEDED(hr) && prc)
967  {
968  INT x, y;
969 
970  for (y=0; y<prc->Height; y++)
971  for (x=0; x<prc->Width; x++)
972  {
973  BYTE alpha = pbBuffer[cbStride*y+4*x+3];
974  if (alpha != 255)
975  {
976  pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255;
977  pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255;
978  pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255;
979  }
980  }
981  }
982  return hr;
983  }
984 }
985 
987  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
988 {
989  HRESULT hr;
990 
991  switch (source_format)
992  {
993  case format_24bppBGR:
994  case format_24bppRGB:
995  if (prc)
996  {
997  hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
998  if (SUCCEEDED(hr) && source_format == format_24bppRGB)
999  reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride);
1000  return hr;
1001  }
1002  return S_OK;
1003  case format_32bppBGR:
1004  case format_32bppBGRA:
1005  case format_32bppPBGRA:
1006  if (prc)
1007  {
1008  HRESULT res;
1009  INT x, y;
1010  BYTE *srcdata;
1011  UINT srcstride, srcdatasize;
1012  const BYTE *srcrow;
1013  const BYTE *srcpixel;
1014  BYTE *dstrow;
1015  BYTE *dstpixel;
1016 
1017  srcstride = 4 * prc->Width;
1018  srcdatasize = srcstride * prc->Height;
1019 
1020  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1021  if (!srcdata) return E_OUTOFMEMORY;
1022 
1023  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
1024 
1025  if (SUCCEEDED(res))
1026  {
1027  srcrow = srcdata;
1028  dstrow = pbBuffer;
1029  for (y=0; y<prc->Height; y++) {
1030  srcpixel=srcrow;
1031  dstpixel=dstrow;
1032  for (x=0; x<prc->Width; x++) {
1033  *dstpixel++=*srcpixel++; /* blue */
1034  *dstpixel++=*srcpixel++; /* green */
1035  *dstpixel++=*srcpixel++; /* red */
1036  srcpixel++; /* alpha */
1037  }
1038  srcrow += srcstride;
1039  dstrow += cbStride;
1040  }
1041  }
1042 
1043  HeapFree(GetProcessHeap(), 0, srcdata);
1044 
1045  return res;
1046  }
1047  return S_OK;
1048 
1049  case format_32bppGrayFloat:
1050  if (prc)
1051  {
1052  BYTE *srcdata;
1053  UINT srcstride, srcdatasize;
1054 
1055  srcstride = 4 * prc->Width;
1056  srcdatasize = srcstride * prc->Height;
1057 
1058  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1059  if (!srcdata) return E_OUTOFMEMORY;
1060 
1061  hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
1062 
1063  if (SUCCEEDED(hr))
1064  {
1065  INT x, y;
1066  BYTE *src = srcdata, *dst = pbBuffer;
1067 
1068  for (y = 0; y < prc->Height; y++)
1069  {
1070  float *gray_float = (float *)src;
1071  BYTE *bgr = dst;
1072 
1073  for (x = 0; x < prc->Width; x++)
1074  {
1075  BYTE gray = (BYTE)floorf(to_sRGB_component(gray_float[x]) * 255.0f + 0.51f);
1076  *bgr++ = gray;
1077  *bgr++ = gray;
1078  *bgr++ = gray;
1079  }
1080  src += srcstride;
1081  dst += cbStride;
1082  }
1083  }
1084 
1085  HeapFree(GetProcessHeap(), 0, srcdata);
1086 
1087  return hr;
1088  }
1089  return S_OK;
1090 
1091  case format_32bppCMYK:
1092  if (prc)
1093  {
1094  BYTE *srcdata;
1095  UINT srcstride, srcdatasize;
1096 
1097  srcstride = 4 * prc->Width;
1098  srcdatasize = srcstride * prc->Height;
1099 
1100  srcdata = heap_alloc(srcdatasize);
1101  if (!srcdata) return E_OUTOFMEMORY;
1102 
1103  hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
1104  if (SUCCEEDED(hr))
1105  {
1106  INT x, y;
1107  BYTE *src = srcdata, *dst = pbBuffer;
1108 
1109  for (y = 0; y < prc->Height; y++)
1110  {
1111  BYTE *cmyk = src;
1112  BYTE *bgr = dst;
1113 
1114  for (x = 0; x < prc->Width; x++)
1115  {
1116  BYTE c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
1117  bgr[0] = (255 - y) * (255 - k) / 255; /* B */
1118  bgr[1] = (255 - m) * (255 - k) / 255; /* G */
1119  bgr[2] = (255 - c) * (255 - k) / 255; /* R */
1120  cmyk += 4;
1121  bgr += 3;
1122  }
1123  src += srcstride;
1124  dst += cbStride;
1125  }
1126  }
1127 
1128  heap_free(srcdata);
1129  return hr;
1130  }
1131  return S_OK;
1132 
1133  default:
1134  FIXME("Unimplemented conversion path!\n");
1136  }
1137 }
1138 
1140  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
1141 {
1142  HRESULT hr;
1143 
1144  switch (source_format)
1145  {
1146  case format_24bppBGR:
1147  case format_24bppRGB:
1148  if (prc)
1149  {
1150  hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
1151  if (SUCCEEDED(hr) && source_format == format_24bppBGR)
1152  reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride);
1153  return hr;
1154  }
1155  return S_OK;
1156  case format_32bppBGR:
1157  case format_32bppBGRA:
1158  case format_32bppPBGRA:
1159  if (prc)
1160  {
1161  HRESULT res;
1162  INT x, y;
1163  BYTE *srcdata;
1164  UINT srcstride, srcdatasize;
1165  const BYTE *srcrow;
1166  const BYTE *srcpixel;
1167  BYTE *dstrow;
1168  BYTE *dstpixel;
1169  BYTE tmppixel[3];
1170 
1171  srcstride = 4 * prc->Width;
1172  srcdatasize = srcstride * prc->Height;
1173 
1174  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1175  if (!srcdata) return E_OUTOFMEMORY;
1176 
1177  res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
1178 
1179  if (SUCCEEDED(res))
1180  {
1181  srcrow = srcdata;
1182  dstrow = pbBuffer;
1183  for (y=0; y<prc->Height; y++) {
1184  srcpixel=srcrow;
1185  dstpixel=dstrow;
1186  for (x=0; x<prc->Width; x++) {
1187  tmppixel[0]=*srcpixel++; /* blue */
1188  tmppixel[1]=*srcpixel++; /* green */
1189  tmppixel[2]=*srcpixel++; /* red */
1190  srcpixel++; /* alpha */
1191 
1192  *dstpixel++=tmppixel[2]; /* red */
1193  *dstpixel++=tmppixel[1]; /* green */
1194  *dstpixel++=tmppixel[0]; /* blue */
1195  }
1196  srcrow += srcstride;
1197  dstrow += cbStride;
1198  }
1199  }
1200 
1201  HeapFree(GetProcessHeap(), 0, srcdata);
1202 
1203  return res;
1204  }
1205  return S_OK;
1206  default:
1207  FIXME("Unimplemented conversion path!\n");
1209  }
1210 }
1211 
1213  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
1214 {
1215  HRESULT hr;
1216 
1217  switch (source_format)
1218  {
1219  case format_32bppBGR:
1220  case format_32bppBGRA:
1221  case format_32bppPBGRA:
1222  case format_32bppGrayFloat:
1223  if (prc)
1224  {
1225  hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
1226  break;
1227  }
1228  return S_OK;
1229 
1230  default:
1231  hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
1232  break;
1233  }
1234 
1235  if (SUCCEEDED(hr) && prc && source_format != format_32bppGrayFloat)
1236  {
1237  INT x, y;
1238  BYTE *p = pbBuffer;
1239 
1240  for (y = 0; y < prc->Height; y++)
1241  {
1242  BYTE *bgr = p;
1243  for (x = 0; x < prc->Width; x++)
1244  {
1245  float gray = (bgr[2] * 0.2126f + bgr[1] * 0.7152f + bgr[0] * 0.0722f) / 255.0f;
1246  *(float *)bgr = gray;
1247  bgr += 4;
1248  }
1249  p += cbStride;
1250  }
1251  }
1252  return hr;
1253 }
1254 
1256  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
1257 {
1258  HRESULT hr;
1259  BYTE *srcdata;
1260  UINT srcstride, srcdatasize;
1261 
1262  if (source_format == format_8bppGray)
1263  {
1264  if (prc)
1265  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
1266 
1267  return S_OK;
1268  }
1269 
1270  if (source_format == format_32bppGrayFloat)
1271  {
1272  hr = S_OK;
1273 
1274  if (prc)
1275  {
1276  srcstride = 4 * prc->Width;
1277  srcdatasize = srcstride * prc->Height;
1278 
1279  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1280  if (!srcdata) return E_OUTOFMEMORY;
1281 
1282  hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
1283  if (SUCCEEDED(hr))
1284  {
1285  INT x, y;
1286  BYTE *src = srcdata, *dst = pbBuffer;
1287 
1288  for (y=0; y < prc->Height; y++)
1289  {
1290  float *srcpixel = (float*)src;
1291  BYTE *dstpixel = dst;
1292 
1293  for (x=0; x < prc->Width; x++)
1294  *dstpixel++ = (BYTE)floorf(to_sRGB_component(*srcpixel++) * 255.0f + 0.51f);
1295 
1296  src += srcstride;
1297  dst += cbStride;
1298  }
1299  }
1300 
1301  HeapFree(GetProcessHeap(), 0, srcdata);
1302  }
1303 
1304  return hr;
1305  }
1306 
1307  srcstride = 3 * prc->Width;
1308  srcdatasize = srcstride * prc->Height;
1309 
1310  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1311  if (!srcdata) return E_OUTOFMEMORY;
1312 
1313  hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format);
1314  if (SUCCEEDED(hr) && prc)
1315  {
1316  INT x, y;
1317  BYTE *src = srcdata, *dst = pbBuffer;
1318 
1319  for (y = 0; y < prc->Height; y++)
1320  {
1321  BYTE *bgr = src;
1322 
1323  for (x = 0; x < prc->Width; x++)
1324  {
1325  float gray = (bgr[2] * 0.2126f + bgr[1] * 0.7152f + bgr[0] * 0.0722f) / 255.0f;
1326 
1327  gray = to_sRGB_component(gray) * 255.0f;
1328  dst[x] = (BYTE)floorf(gray + 0.51f);
1329  bgr += 3;
1330  }
1331  src += srcstride;
1332  dst += cbStride;
1333  }
1334  }
1335 
1336  HeapFree(GetProcessHeap(), 0, srcdata);
1337  return hr;
1338 }
1339 
1341 {
1342  UINT best_diff, best_index, i;
1343 
1344  best_diff = ~0;
1345  best_index = 0;
1346 
1347  for (i = 0; i < count; i++)
1348  {
1349  BYTE pal_r, pal_g, pal_b;
1350  DWORD diff_r, diff_g, diff_b, diff;
1351 
1352  pal_r = colors[i] >> 16;
1353  pal_g = colors[i] >> 8;
1354  pal_b = colors[i];
1355 
1356  diff_r = r - pal_r;
1357  diff_g = g - pal_g;
1358  diff_b = b - pal_b;
1359 
1360  diff = diff_r * diff_r + diff_g * diff_g + diff_b * diff_b;
1361  if (diff == 0) return i;
1362 
1363  if (diff < best_diff)
1364  {
1365  best_diff = diff;
1366  best_index = i;
1367  }
1368  }
1369 
1370  return best_index;
1371 }
1372 
1374  UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
1375 {
1376  HRESULT hr;
1377  BYTE *srcdata;
1378  WICColor colors[256];
1379  UINT srcstride, srcdatasize, count;
1380 
1381  if (source_format == format_8bppIndexed)
1382  {
1383  if (prc)
1384  return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
1385 
1386  return S_OK;
1387  }
1388 
1389  if (!This->palette) return WINCODEC_ERR_WRONGSTATE;
1390 
1391  hr = IWICPalette_GetColors(This->palette, 256, colors, &count);
1392  if (hr != S_OK) return hr;
1393 
1394  srcstride = 3 * prc->Width;
1395  srcdatasize = srcstride * prc->Height;
1396 
1397  srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
1398  if (!srcdata) return E_OUTOFMEMORY;
1399 
1400  hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format);
1401  if (SUCCEEDED(hr) && prc)
1402  {
1403  INT x, y;
1404  BYTE *src = srcdata, *dst = pbBuffer;
1405 
1406  for (y = 0; y < prc->Height; y++)
1407  {
1408  BYTE *bgr = src;
1409 
1410  for (x = 0; x < prc->Width; x++)
1411  {
1412  dst[x] = rgb_to_palette_index(bgr[2], bgr[1], bgr[0], colors, count);
1413  bgr += 3;
1414  }
1415  src += srcstride;
1416  dst += cbStride;
1417  }
1418  }
1419 
1420  HeapFree(GetProcessHeap(), 0, srcdata);
1421  return hr;
1422 }
1423 
1424 static const struct pixelformatinfo supported_formats[] = {
1425  {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
1426  {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
1427  {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
1428  {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed},
1429  {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
1430  {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
1431  {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
1432  {format_8bppGray, &GUID_WICPixelFormat8bppGray, copypixels_to_8bppGray},
1433  {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL},
1434  {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL},
1435  {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL},
1436  {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL},
1437  {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, copypixels_to_24bppBGR},
1438  {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB},
1439  {format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat},
1440  {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
1441  {format_32bppRGB, &GUID_WICPixelFormat32bppRGB, copypixels_to_32bppRGB},
1442  {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
1443  {format_32bppRGBA, &GUID_WICPixelFormat32bppRGBA, copypixels_to_32bppRGBA},
1444  {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA},
1445  {format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA},
1446  {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL},
1447  {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL},
1448  {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL},
1449  {0}
1450 };
1451 
1453 {
1454  UINT i;
1455 
1456  for (i=0; supported_formats[i].guid; i++)
1458 
1459  return NULL;
1460 }
1461 
1463  void **ppv)
1464 {
1466  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1467 
1468  if (!ppv) return E_INVALIDARG;
1469 
1470  if (IsEqualIID(&IID_IUnknown, iid) ||
1471  IsEqualIID(&IID_IWICBitmapSource, iid) ||
1472  IsEqualIID(&IID_IWICFormatConverter, iid))
1473  {
1474  *ppv = &This->IWICFormatConverter_iface;
1475  }
1476  else
1477  {
1478  *ppv = NULL;
1479  return E_NOINTERFACE;
1480  }
1481 
1482  IUnknown_AddRef((IUnknown*)*ppv);
1483  return S_OK;
1484 }
1485 
1487 {
1490 
1491  TRACE("(%p) refcount=%u\n", iface, ref);
1492 
1493  return ref;
1494 }
1495 
1497 {
1500 
1501  TRACE("(%p) refcount=%u\n", iface, ref);
1502 
1503  if (ref == 0)
1504  {
1505  This->lock.DebugInfo->Spare[0] = 0;
1506  DeleteCriticalSection(&This->lock);
1507  if (This->source) IWICBitmapSource_Release(This->source);
1508  if (This->palette) IWICPalette_Release(This->palette);
1509  HeapFree(GetProcessHeap(), 0, This);
1510  }
1511 
1512  return ref;
1513 }
1514 
1516  UINT *puiWidth, UINT *puiHeight)
1517 {
1519 
1520  TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
1521 
1522  if (This->source)
1523  return IWICBitmapSource_GetSize(This->source, puiWidth, puiHeight);
1524  else
1526 }
1527 
1529  WICPixelFormatGUID *pPixelFormat)
1530 {
1532 
1533  TRACE("(%p,%p)\n", iface, pPixelFormat);
1534 
1535  if (This->source)
1536  memcpy(pPixelFormat, This->dst_format->guid, sizeof(GUID));
1537  else
1539 
1540  return S_OK;
1541 }
1542 
1544  double *pDpiX, double *pDpiY)
1545 {
1547 
1548  TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
1549 
1550  if (This->source)
1551  return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY);
1552  else
1554 }
1555 
1558 {
1560 
1561  TRACE("(%p,%p)\n", iface, palette);
1562 
1563  if (!palette) return E_INVALIDARG;
1564  if (!This->source) return WINCODEC_ERR_WRONGSTATE;
1565 
1566  if (!This->palette)
1567  {
1568  HRESULT hr;
1569  UINT bpp;
1570 
1571  hr = get_pixelformat_bpp(This->dst_format->guid, &bpp);
1572  if (hr != S_OK) return hr;
1573  if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE;
1574  return IWICBitmapSource_CopyPalette(This->source, palette);
1575  }
1576 
1577  return IWICPalette_InitializeFromPalette(palette, This->palette);
1578 }
1579 
1581  const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
1582 {
1584  WICRect rc;
1585  HRESULT hr;
1586  TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
1587 
1588  if (This->source)
1589  {
1590  if (!prc)
1591  {
1592  UINT width, height;
1593  hr = IWICBitmapSource_GetSize(This->source, &width, &height);
1594  if (FAILED(hr)) return hr;
1595  rc.X = 0;
1596  rc.Y = 0;
1597  rc.Width = width;
1598  rc.Height = height;
1599  prc = &rc;
1600  }
1601 
1602  return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
1603  pbBuffer, This->src_format->format);
1604  }
1605  else
1606  return WINCODEC_ERR_WRONGSTATE;
1607 }
1608 
1611  IWICPalette *palette, double alpha_threshold, WICBitmapPaletteType palette_type)
1612 {
1614  const struct pixelformatinfo *srcinfo, *dstinfo;
1615  GUID srcFormat;
1616  HRESULT res;
1617 
1618  TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
1619  dither, palette, alpha_threshold, palette_type);
1620 
1621  if (!palette)
1622  {
1623  UINT bpp;
1624  res = get_pixelformat_bpp(dstFormat, &bpp);
1625  if (res != S_OK) return res;
1626 
1628  if (res != S_OK) return res;
1629 
1630  switch (palette_type)
1631  {
1633  IWICPalette_Release(palette);
1634  palette = NULL;
1635  if (bpp <= 8) return E_INVALIDARG;
1636  break;
1637 
1639  {
1640  if (bpp <= 8)
1641  res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
1642  break;
1643  }
1644 
1645  default:
1646  if (bpp <= 8)
1647  res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
1648  break;
1649  }
1650 
1651  if (res != S_OK)
1652  {
1653  IWICPalette_Release(palette);
1654  return res;
1655  }
1656  }
1657  else
1658  IWICPalette_AddRef(palette);
1659 
1660  EnterCriticalSection(&This->lock);
1661 
1662  if (This->source)
1663  {
1665  goto end;
1666  }
1667 
1668  res = IWICBitmapSource_GetPixelFormat(source, &srcFormat);
1669  if (FAILED(res)) goto end;
1670 
1671  srcinfo = get_formatinfo(&srcFormat);
1672  if (!srcinfo)
1673  {
1675  FIXME("Unsupported source format %s\n", debugstr_guid(&srcFormat));
1676  goto end;
1677  }
1678 
1679  dstinfo = get_formatinfo(dstFormat);
1680  if (!dstinfo)
1681  {
1683  FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat));
1684  goto end;
1685  }
1686 
1687  if (dstinfo->copy_function)
1688  {
1689  IWICBitmapSource_AddRef(source);
1690  This->src_format = srcinfo;
1691  This->dst_format = dstinfo;
1692  This->dither = dither;
1693  This->alpha_threshold = alpha_threshold;
1694  This->palette = palette;
1695  This->source = source;
1696  }
1697  else
1698  {
1699  FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
1701  }
1702 
1703 end:
1704 
1705  LeaveCriticalSection(&This->lock);
1706 
1707  if (res != S_OK && palette)
1708  IWICPalette_Release(palette);
1709 
1710  return res;
1711 }
1712 
1714  REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat,
1715  BOOL *pfCanConvert)
1716 {
1718  const struct pixelformatinfo *srcinfo, *dstinfo;
1719 
1720  TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat),
1721  debugstr_guid(dstPixelFormat), pfCanConvert);
1722 
1723  srcinfo = get_formatinfo(srcPixelFormat);
1724  if (!srcinfo)
1725  {
1726  FIXME("Unsupported source format %s\n", debugstr_guid(srcPixelFormat));
1728  }
1729 
1730  dstinfo = get_formatinfo(dstPixelFormat);
1731  if (!dstinfo)
1732  {
1733  FIXME("Unsupported destination format %s\n", debugstr_guid(dstPixelFormat));
1735  }
1736 
1737  if (dstinfo->copy_function &&
1738  SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format)))
1739  *pfCanConvert = TRUE;
1740  else
1741  {
1742  FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(srcPixelFormat), debugstr_guid(dstPixelFormat));
1743  *pfCanConvert = FALSE;
1744  }
1745 
1746  return S_OK;
1747 }
1748 
1749 static const IWICFormatConverterVtbl FormatConverter_Vtbl = {
1760 };
1761 
1763 {
1765  HRESULT ret;
1766 
1767  TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
1768 
1769  *ppv = NULL;
1770 
1771  This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter));
1772  if (!This) return E_OUTOFMEMORY;
1773 
1774  This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl;
1775  This->ref = 1;
1776  This->source = NULL;
1777  This->palette = NULL;
1779  This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
1780 
1781  ret = IWICFormatConverter_QueryInterface(&This->IWICFormatConverter_iface, iid, ppv);
1782  IWICFormatConverter_Release(&This->IWICFormatConverter_iface);
1783 
1784  return ret;
1785 }
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
Definition: converter.c:1580
#define HRESULT
Definition: msvc.h:9
GLint GLint GLsizei width
Definition: gl.h:1546
static const struct pixelformatinfo * get_formatinfo(const WICPixelFormatGUID *format)
Definition: converter.c:1452
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static HRESULT copypixels_to_32bppRGBA(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:867
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:920
#define DWORD_PTR
Definition: treelist.c:76
HRESULT hr
Definition: shlfolder.c:183
Definition: scsiwmi.h:51
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint GLsizei count
Definition: gl.h:1545
HRESULT PaletteImpl_Create(IWICPalette **palette)
Definition: palette.c:899
static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:888
WICBitmapDitherType dither
Definition: converter.c:81
REFIID LPVOID * ppv
Definition: atlbase.h:39
static HRESULT copypixels_to_32bppRGB(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:904
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface, WICPixelFormatGUID *pPixelFormat)
Definition: converter.c:1528
#define WINCODEC_ERR_NOTINITIALIZED
Definition: winerror.h:3277
GLuint GLuint end
Definition: gl.h:1545
struct FormatConverter FormatConverter
const struct pixelformatinfo * src_format
Definition: converter.c:80
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static float to_sRGB_component(float f)
Definition: converter.c:96
int32_t INT
Definition: typedefs.h:56
Definition: send.c:47
const GLfloat * m
Definition: glext.h:10848
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:953
static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface, UINT *puiWidth, UINT *puiHeight)
Definition: converter.c:1515
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
HRESULT FormatConverter_CreateInstance(REFIID iid, void **ppv)
Definition: converter.c:1762
IWICBitmapSource * source
Definition: converter.c:79
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
IWICFormatConverter IWICFormatConverter_iface
Definition: converter.c:77
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
copyfunc copy_function
Definition: converter.c:73
pixelformat
Definition: converter.c:40
INT Height
Definition: wincodec.idl:239
#define debugstr_guid
Definition: kernel32.h:35
GLclampf GLclampf blue
Definition: gl.h:1740
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define b
Definition: ke_i.h:79
static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:143
_Check_return_ __CRT_INLINE float powf(_In_ float x, _In_ float y)
Definition: math.h:216
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
#define floorf(x)
Definition: mymath.h:65
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
WICBitmapPaletteType
Definition: wincodec.idl:90
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
LONG HRESULT
Definition: typedefs.h:77
static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:1373
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
HRESULT(* copyfunc)(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:67
unsigned short WORD
Definition: ntddk_ex.h:93
GLclampf green
Definition: gl.h:1740
CRITICAL_SECTION lock
Definition: converter.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, IWICBitmapSource *source, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither, IWICPalette *palette, double alpha_threshold, WICBitmapPaletteType palette_type)
Definition: converter.c:1609
#define red
Definition: linetest.c:67
int ret
#define InterlockedDecrement
Definition: armddk.h:52
static HRESULT copypixels_to_32bppGrayFloat(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:1212
static const char * debug_wic_rect(const WICRect *rect)
static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface, IWICPalette *palette)
Definition: converter.c:1556
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
j_compress_ptr dstinfo
Definition: jpeglib.h:1097
GLenum src
Definition: glext.h:6340
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
Definition: winerror.h:3300
static FormatConverter * impl_from_IWICFormatConverter(IWICFormatConverter *iface)
Definition: converter.c:138
static HPALETTE palette
Definition: clipboard.c:1345
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
const struct pixelformatinfo * dst_format
Definition: converter.c:80
static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:986
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3273
#define S_OK
Definition: intsafe.h:59
WICBitmapPaletteType palette_type
Definition: image.c:53
#define InterlockedIncrement
Definition: armddk.h:53
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define f
Definition: ke_i.h:83
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
Definition: winerror.h:3299
static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:1139
GLenum GLenum dst
Definition: glext.h:6340
enum pixelformat format
Definition: converter.c:71
static const struct pixelformatinfo supported_formats[]
Definition: converter.c:1424
static float from_sRGB_component(float f)
Definition: converter.c:89
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
double alpha_threshold
Definition: converter.c:82
INT Width
Definition: wincodec.idl:238
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface, REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat, BOOL *pfCanConvert)
Definition: converter.c:1713
GLuint res
Definition: glext.h:9613
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface, double *pDpiX, double *pDpiY)
Definition: converter.c:1543
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
WICBitmapDitherType
Definition: wincodec.idl:55
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
Definition: main.c:212
DWORD bpp
Definition: surface.c:181
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
Definition: converter.c:1486
GLfloat GLfloat p
Definition: glext.h:8902
_Out_ LPRECT prc
Definition: ntgdi.h:1658
static UINT rgb_to_palette_index(BYTE r, BYTE g, BYTE b, WICColor *colors, UINT count)
Definition: converter.c:1340
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs)
HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp)
Definition: main.c:231
static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid, void **ppv)
Definition: converter.c:1462
UINT32 WICColor
Definition: wincodec.idl:250
const WICPixelFormatGUID * guid
Definition: converter.c:72
int k
Definition: mpi.c:3369
#define HeapFree(x, y, z)
Definition: compat.h:394
static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
Definition: converter.c:1496
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
IWICPalette * palette
Definition: converter.c:83
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
Definition: converter.c:1255
static const IWICFormatConverterVtbl FormatConverter_Vtbl
Definition: converter.c:1749
static BOOL heap_free(void *mem)
Definition: appwiz.h:75