ReactOS  0.4.11-dev-195-gef016bf
bmpdecode.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009 Vincent Povirk for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "config.h"
20 
21 #include <assert.h>
22 #include <stdarg.h>
23 
24 #define COBJMACROS
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "wingdi.h"
30 #include "objbase.h"
31 
32 #include "wincodecs_private.h"
33 
34 #include "wine/debug.h"
35 
37 
38 typedef struct {
50  /* same as BITMAPINFOHEADER until this point */
60 
61 typedef HRESULT (*ReadDataFunc)(BmpDecoder* This);
62 
63 struct BmpDecoder {
71  BITMAPV5HEADER bih;
78  CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */
79  int packed; /* If TRUE, don't look for a file header and assume a packed DIB. */
80  int icoframe; /* If TRUE, this is a frame of a .ico file. */
81 };
82 
84 {
85  return CONTAINING_RECORD(iface, BmpDecoder, IWICBitmapDecoder_iface);
86 }
87 
89 {
90  return CONTAINING_RECORD(iface, BmpDecoder, IWICBitmapFrameDecode_iface);
91 }
92 
94  void **ppv)
95 {
97 
98  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
99 
100  if (!ppv) return E_INVALIDARG;
101 
102  if (IsEqualIID(&IID_IUnknown, iid) ||
103  IsEqualIID(&IID_IWICBitmapSource, iid) ||
104  IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
105  {
106  *ppv = &This->IWICBitmapFrameDecode_iface;
107  }
108  else
109  {
110  *ppv = NULL;
111  return E_NOINTERFACE;
112  }
113 
114  IUnknown_AddRef((IUnknown*)*ppv);
115  return S_OK;
116 }
117 
119 {
121 
122  return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
123 }
124 
126 {
128 
129  return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
130 }
131 
133  UINT *puiWidth, UINT *puiHeight)
134 {
136  TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
137 
138  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
139  {
140  BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
141  *puiWidth = bch->bcWidth;
142  *puiHeight = bch->bcHeight;
143  }
144  else
145  {
146  *puiWidth = This->bih.bV5Width;
147  *puiHeight = abs(This->bih.bV5Height);
148  }
149  return S_OK;
150 }
151 
153  WICPixelFormatGUID *pPixelFormat)
154 {
156  TRACE("(%p,%p)\n", iface, pPixelFormat);
157 
158  memcpy(pPixelFormat, This->pixelformat, sizeof(GUID));
159 
160  return S_OK;
161 }
162 
163 static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, double *pDpiY)
164 {
165  LONG resx = 0, resy = 0;
166 
167  switch (bih->bV5Size)
168  {
169  default:
170  case sizeof(BITMAPCOREHEADER):
171  break;
172 
173  case sizeof(BITMAPCOREHEADER2):
174  case sizeof(BITMAPINFOHEADER):
175  case sizeof(BITMAPV4HEADER):
176  case sizeof(BITMAPV5HEADER):
177  resx = bih->bV5XPelsPerMeter;
178  resy = bih->bV5YPelsPerMeter;
179  break;
180  }
181 
182  if (!resx || !resy)
183  {
184  *pDpiX = 96.0;
185  *pDpiY = 96.0;
186  }
187  else
188  {
189  *pDpiX = resx * 0.0254;
190  *pDpiY = resy * 0.0254;
191  }
192 
193  return S_OK;
194 }
195 
197  double *pDpiX, double *pDpiY)
198 {
200  TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
201 
202  return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY);
203 }
204 
206  IWICPalette *pIPalette)
207 {
208  HRESULT hr;
210  int count;
211  WICColor *wiccolors=NULL;
212  RGBTRIPLE *bgrcolors=NULL;
213 
214  TRACE("(%p,%p)\n", iface, pIPalette);
215 
216  EnterCriticalSection(&This->lock);
217 
218  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
219  {
220  BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
221  if (bch->bcBitCount <= 8)
222  {
223  /* 2**n colors in BGR format after the header */
224  ULONG tablesize, bytesread;
226  int i;
227 
228  count = 1 << bch->bcBitCount;
229  wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count);
230  tablesize = sizeof(RGBTRIPLE) * count;
231  bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
232  if (!wiccolors || !bgrcolors)
233  {
234  hr = E_OUTOFMEMORY;
235  goto end;
236  }
237 
238  offset.QuadPart = This->palette_offset;
239  hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
240  if (FAILED(hr)) goto end;
241 
242  hr = IStream_Read(This->stream, bgrcolors, tablesize, &bytesread);
243  if (FAILED(hr)) goto end;
244  if (bytesread != tablesize) {
245  hr = E_FAIL;
246  goto end;
247  }
248 
249  for (i=0; i<count; i++)
250  {
251  wiccolors[i] = 0xff000000|
252  (bgrcolors[i].rgbtRed<<16)|
253  (bgrcolors[i].rgbtGreen<<8)|
254  bgrcolors[i].rgbtBlue;
255  }
256  }
257  else
258  {
260  goto end;
261  }
262  }
263  else
264  {
265  if (This->bih.bV5BitCount <= 8)
266  {
267  ULONG tablesize, bytesread;
269  int i;
270 
271  if (This->bih.bV5ClrUsed == 0)
272  count = 1 << This->bih.bV5BitCount;
273  else
274  count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount);
275 
276  tablesize = sizeof(WICColor) * count;
277  wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
278  if (!wiccolors)
279  {
280  hr = E_OUTOFMEMORY;
281  goto end;
282  }
283 
284  offset.QuadPart = This->palette_offset;
285  hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
286  if (FAILED(hr)) goto end;
287 
288  hr = IStream_Read(This->stream, wiccolors, tablesize, &bytesread);
289  if (FAILED(hr)) goto end;
290  if (bytesread != tablesize) {
291  hr = E_FAIL;
292  goto end;
293  }
294 
295  /* convert from BGR to BGRA by setting alpha to 100% */
296  for (i=0; i<count; i++)
297  wiccolors[i] |= 0xff000000;
298  }
299  else
300  {
302  goto end;
303  }
304  }
305 
306 end:
307 
308  LeaveCriticalSection(&This->lock);
309 
310  if (SUCCEEDED(hr))
311  hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
312 
313  HeapFree(GetProcessHeap(), 0, wiccolors);
314  HeapFree(GetProcessHeap(), 0, bgrcolors);
315  return hr;
316 }
317 
319  const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
320 {
322  HRESULT hr=S_OK;
323  UINT width, height;
324  TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
325 
326  EnterCriticalSection(&This->lock);
327  if (!This->imagedata)
328  {
329  hr = This->read_data_func(This);
330  }
331  LeaveCriticalSection(&This->lock);
332  if (FAILED(hr)) return hr;
333 
334  hr = BmpFrameDecode_GetSize(iface, &width, &height);
335  if (FAILED(hr)) return hr;
336 
337  return copy_pixels(This->bitsperpixel, This->imagedatastart,
338  width, height, This->stride,
339  prc, cbStride, cbBufferSize, pbBuffer);
340 }
341 
343  IWICMetadataQueryReader **ppIMetadataQueryReader)
344 {
345  TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
347 }
348 
350  UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
351 {
352  TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
354 }
355 
357  IWICBitmapSource **ppIThumbnail)
358 {
359  TRACE("(%p,%p)\n", iface, ppIThumbnail);
361 }
362 
364 {
365  UINT bytesperrow;
366  UINT width, height;
367  UINT datasize;
368  int bottomup;
369  HRESULT hr;
370  LARGE_INTEGER offbits;
371  ULONG bytesread;
372 
373  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
374  {
375  BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
376  width = bch->bcWidth;
377  height = bch->bcHeight;
378  bottomup = 1;
379  }
380  else
381  {
382  width = This->bih.bV5Width;
383  height = abs(This->bih.bV5Height);
384  bottomup = (This->bih.bV5Height > 0);
385  }
386 
387  /* row sizes in BMP files must be divisible by 4 bytes */
388  bytesperrow = (((width * This->bitsperpixel)+31)/32)*4;
389  datasize = bytesperrow * height;
390 
391  This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
392  if (!This->imagedata) return E_OUTOFMEMORY;
393 
394  offbits.QuadPart = This->image_offset;
395  hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
396  if (FAILED(hr)) goto fail;
397 
398  hr = IStream_Read(This->stream, This->imagedata, datasize, &bytesread);
399  if (FAILED(hr) || bytesread != datasize) goto fail;
400 
401  if (bottomup)
402  {
403  This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
404  This->stride = -bytesperrow;
405  }
406  else
407  {
408  This->imagedatastart = This->imagedata;
409  This->stride = bytesperrow;
410  }
411  return S_OK;
412 
413 fail:
414  HeapFree(GetProcessHeap(), 0, This->imagedata);
415  This->imagedata = NULL;
416  if (SUCCEEDED(hr)) hr = E_FAIL;
417  return hr;
418 }
419 
421 {
422  HRESULT hr;
423  UINT width, height;
424 
425  hr = IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height);
426 
427  if (SUCCEEDED(hr))
428  {
430  }
431 
432  if (SUCCEEDED(hr))
433  {
435  width, height, This->stride);
436  }
437 
438  return hr;
439 }
440 
441 static HRESULT ReadByte(IStream *stream, BYTE *buffer, ULONG buffer_size,
442  ULONG *cursor, ULONG *bytesread, BYTE *result)
443 {
444  HRESULT hr=S_OK;
445 
446  if (*bytesread == 0 || *cursor == *bytesread)
447  {
448  hr = IStream_Read(stream, buffer, buffer_size, bytesread);
449  *cursor = 0;
450  }
451 
452  if (SUCCEEDED(hr))
453  {
454  if (*cursor < *bytesread)
455  *result = buffer[(*cursor)++];
456  else
457  hr = E_FAIL;
458  }
459 
460  return hr;
461 }
462 
464 {
465  UINT bytesperrow;
466  UINT width, height;
467  BYTE rledata[4096];
468  UINT datasize, palettesize;
469  DWORD palette[256];
470  UINT x, y;
471  DWORD *bgrdata;
472  HRESULT hr;
473  LARGE_INTEGER offbits;
474  ULONG cursor=0, bytesread=0;
475 
476  width = This->bih.bV5Width;
477  height = abs(This->bih.bV5Height);
478  bytesperrow = width * 4;
479  datasize = bytesperrow * height;
480  if (This->bih.bV5ClrUsed && This->bih.bV5ClrUsed < 256)
481  palettesize = 4 * This->bih.bV5ClrUsed;
482  else
483  palettesize = 4 * 256;
484 
485  This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
486  if (!This->imagedata)
487  {
488  hr = E_OUTOFMEMORY;
489  goto fail;
490  }
491 
492  /* read palette */
493  offbits.QuadPart = This->palette_offset;
494  hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
495  if (FAILED(hr)) goto fail;
496 
497  hr = IStream_Read(This->stream, palette, palettesize, &bytesread);
498  if (FAILED(hr) || bytesread != palettesize) goto fail;
499 
500  /* read RLE data */
501  offbits.QuadPart = This->image_offset;
502  hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
503  if (FAILED(hr)) goto fail;
504 
505  /* decode RLE */
506  bgrdata = (DWORD*)This->imagedata;
507  x = 0;
508  y = 0;
509  cursor = 0;
510  bytesread = 0;
511  while (y < height)
512  {
513  BYTE length;
514  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &length);
515 
516  if (FAILED(hr))
517  goto fail;
518  else if (length == 0)
519  {
520  /* escape code */
521  BYTE escape;
522  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &escape);
523  if (FAILED(hr))
524  goto fail;
525  switch(escape)
526  {
527  case 0: /* end of line */
528  x = 0;
529  y++;
530  break;
531  case 1: /* end of bitmap */
532  goto end;
533  case 2: /* delta */
534  {
535  BYTE dx, dy;
536  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &dx);
537  if (SUCCEEDED(hr))
538  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &dy);
539  if (FAILED(hr))
540  goto fail;
541  x += dx;
542  y += dy;
543  break;
544  }
545  default: /* absolute mode */
546  length = escape;
547  while (length-- && x < width)
548  {
549  BYTE index;
550  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &index);
551  if (FAILED(hr))
552  goto fail;
553  bgrdata[y*width + x++] = palette[index];
554  }
555  if (escape & 1)
556  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &length); /* skip pad byte */
557  if (FAILED(hr))
558  goto fail;
559  }
560  }
561  else
562  {
563  BYTE index;
564  DWORD color;
565  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &index);
566  if (FAILED(hr))
567  goto fail;
568  color = palette[index];
569  while (length-- && x < width)
570  bgrdata[y*width + x++] = color;
571  }
572  }
573 
574 end:
575  This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
576  This->stride = -bytesperrow;
577 
578  return S_OK;
579 
580 fail:
581  HeapFree(GetProcessHeap(), 0, This->imagedata);
582  This->imagedata = NULL;
583  if (SUCCEEDED(hr)) hr = E_FAIL;
584  return hr;
585 }
586 
588 {
589  UINT bytesperrow;
590  UINT width, height;
591  BYTE rledata[4096];
592  UINT datasize, palettesize;
593  DWORD palette[16];
594  UINT x, y;
595  DWORD *bgrdata;
596  HRESULT hr;
597  LARGE_INTEGER offbits;
598  ULONG cursor=0, bytesread=0;
599 
600  width = This->bih.bV5Width;
601  height = abs(This->bih.bV5Height);
602  bytesperrow = width * 4;
603  datasize = bytesperrow * height;
604  if (This->bih.bV5ClrUsed && This->bih.bV5ClrUsed < 16)
605  palettesize = 4 * This->bih.bV5ClrUsed;
606  else
607  palettesize = 4 * 16;
608 
609  This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
610  if (!This->imagedata)
611  {
612  hr = E_OUTOFMEMORY;
613  goto fail;
614  }
615 
616  /* read palette */
617  offbits.QuadPart = This->palette_offset;
618  hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
619  if (FAILED(hr)) goto fail;
620 
621  hr = IStream_Read(This->stream, palette, palettesize, &bytesread);
622  if (FAILED(hr) || bytesread != palettesize) goto fail;
623 
624  /* read RLE data */
625  offbits.QuadPart = This->image_offset;
626  hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
627  if (FAILED(hr)) goto fail;
628 
629  /* decode RLE */
630  bgrdata = (DWORD*)This->imagedata;
631  x = 0;
632  y = 0;
633  cursor = 0;
634  bytesread = 0;
635  while (y < height)
636  {
637  BYTE length;
638  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &length);
639 
640  if (FAILED(hr))
641  goto fail;
642  else if (length == 0)
643  {
644  /* escape code */
645  BYTE escape;
646  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &escape);
647  if (FAILED(hr))
648  goto fail;
649  switch(escape)
650  {
651  case 0: /* end of line */
652  x = 0;
653  y++;
654  break;
655  case 1: /* end of bitmap */
656  goto end;
657  case 2: /* delta */
658  {
659  BYTE dx, dy;
660  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &dx);
661  if (SUCCEEDED(hr))
662  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &dy);
663  if (FAILED(hr))
664  goto fail;
665  x += dx;
666  y += dy;
667  break;
668  }
669  default: /* absolute mode */
670  {
671  BYTE realsize=0;
672  length = escape;
673  while (length-- && x < width)
674  {
675  BYTE colors;
676  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &colors);
677  realsize++;
678  if (FAILED(hr))
679  goto fail;
680  bgrdata[y*width + x++] = palette[colors>>4];
681  if (length-- && x < width)
682  bgrdata[y*width + x++] = palette[colors&0xf];
683  else
684  break;
685  }
686  if (realsize & 1)
687  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &length); /* skip pad byte */
688  if (FAILED(hr))
689  goto fail;
690  }
691  }
692  }
693  else
694  {
695  BYTE colors;
696  DWORD color1;
697  DWORD color2;
698  hr = ReadByte(This->stream, rledata, 4096, &cursor, &bytesread, &colors);
699  if (FAILED(hr))
700  goto fail;
701  color1 = palette[colors>>4];
702  color2 = palette[colors&0xf];
703  while (length-- && x < width)
704  {
705  bgrdata[y*width + x++] = color1;
706  if (length-- && x < width)
707  bgrdata[y*width + x++] = color2;
708  else
709  break;
710  }
711  }
712  }
713 
714 end:
715  This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
716  This->stride = -bytesperrow;
717 
718  return S_OK;
719 
720 fail:
721  HeapFree(GetProcessHeap(), 0, This->imagedata);
722  This->imagedata = NULL;
723  if (SUCCEEDED(hr)) hr = E_FAIL;
724  return hr;
725 }
726 
728 {
729  return E_FAIL;
730 }
731 
733  WORD bitcount; /* 0 for end of list */
740 };
741 
742 static const struct bitfields_format bitfields_formats[] = {
743  {16,0x7c00,0x3e0,0x1f,0,&GUID_WICPixelFormat16bppBGR555,BmpFrameDecode_ReadUncompressed},
744  {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed},
745  {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed},
746  {32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed},
747  {32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8},
748  {0}
749 };
750 
751 static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl = {
763 };
764 
766 {
767  HRESULT hr;
768  ULONG bytestoread, bytesread;
770 
771  if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
772 
773  seek.QuadPart = 0;
774  hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
775  if (FAILED(hr)) return hr;
776 
777  if (!This->packed)
778  {
779  BITMAPFILEHEADER bfh;
780  hr = IStream_Read(stream, &bfh, sizeof(BITMAPFILEHEADER), &bytesread);
781  if (FAILED(hr)) return hr;
782  if (bytesread != sizeof(BITMAPFILEHEADER) ||
783  bfh.bfType != 0x4d42 /* "BM" */) return E_FAIL;
784  This->image_offset = bfh.bfOffBits;
785  }
786 
787  hr = IStream_Read(stream, &This->bih.bV5Size, sizeof(DWORD), &bytesread);
788  if (FAILED(hr)) return hr;
789  if (bytesread != sizeof(DWORD) ||
790  (This->bih.bV5Size != sizeof(BITMAPCOREHEADER) &&
791  This->bih.bV5Size != sizeof(BITMAPCOREHEADER2) &&
792  This->bih.bV5Size != sizeof(BITMAPINFOHEADER) &&
793  This->bih.bV5Size != sizeof(BITMAPV4HEADER) &&
794  This->bih.bV5Size != sizeof(BITMAPV5HEADER))) return E_FAIL;
795 
796  bytestoread = This->bih.bV5Size-sizeof(DWORD);
797  hr = IStream_Read(stream, &This->bih.bV5Width, bytestoread, &bytesread);
798  if (FAILED(hr)) return hr;
799  if (bytestoread != bytesread) return E_FAIL;
800 
801  if (This->packed)
802  This->palette_offset = This->bih.bV5Size;
803  else
804  This->palette_offset = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
805 
806  if (This->icoframe)
807  {
808  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
809  {
810  BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
811  bch->bcHeight /= 2;
812  }
813  else
814  {
815  This->bih.bV5Height /= 2;
816  }
817  }
818 
819  /* if this is a BITMAPINFOHEADER with BI_BITFIELDS compression, we need to
820  read the extra fields */
821  if (This->bih.bV5Size == sizeof(BITMAPINFOHEADER) &&
822  This->bih.bV5Compression == BI_BITFIELDS)
823  {
824  hr = IStream_Read(stream, &This->bih.bV5RedMask, 12, &bytesread);
825  if (FAILED(hr)) return hr;
826  if (bytesread != 12) return E_FAIL;
827  This->bih.bV5AlphaMask = 0;
828  This->palette_offset += 12;
829  }
830 
831  /* decide what kind of bitmap this is and how/if we can read it */
832  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
833  {
834  BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
835  TRACE("BITMAPCOREHEADER with depth=%i\n", bch->bcBitCount);
836  This->bitsperpixel = bch->bcBitCount;
838  switch(bch->bcBitCount)
839  {
840  case 1:
841  This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
842  break;
843  case 2:
844  This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
845  break;
846  case 4:
847  This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
848  break;
849  case 8:
850  This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
851  break;
852  case 24:
853  This->pixelformat = &GUID_WICPixelFormat24bppBGR;
854  break;
855  default:
856  This->pixelformat = &GUID_WICPixelFormatUndefined;
857  WARN("unsupported bit depth %i for BITMAPCOREHEADER\n", bch->bcBitCount);
858  break;
859  }
860  }
861  else /* struct is compatible with BITMAPINFOHEADER */
862  {
863  TRACE("bitmap header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
864  switch(This->bih.bV5Compression)
865  {
866  case BI_RGB:
867  This->bitsperpixel = This->bih.bV5BitCount;
869  switch(This->bih.bV5BitCount)
870  {
871  case 1:
872  This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
873  break;
874  case 2:
875  This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
876  break;
877  case 4:
878  This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
879  break;
880  case 8:
881  This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
882  break;
883  case 16:
884  This->pixelformat = &GUID_WICPixelFormat16bppBGR555;
885  break;
886  case 24:
887  This->pixelformat = &GUID_WICPixelFormat24bppBGR;
888  break;
889  case 32:
890  This->pixelformat = &GUID_WICPixelFormat32bppBGR;
891  break;
892  default:
893  This->pixelformat = &GUID_WICPixelFormatUndefined;
894  FIXME("unsupported bit depth %i for uncompressed RGB\n", This->bih.bV5BitCount);
895  }
896  break;
897  case BI_RLE8:
898  This->bitsperpixel = 32;
900  This->pixelformat = &GUID_WICPixelFormat32bppBGR;
901  break;
902  case BI_RLE4:
903  This->bitsperpixel = 32;
905  This->pixelformat = &GUID_WICPixelFormat32bppBGR;
906  break;
907  case BI_BITFIELDS:
908  {
909  const struct bitfields_format *format;
910  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER2))
911  {
912  /* BCH2 doesn't support bitfields; this is Huffman 1D compression */
913  This->bitsperpixel = 0;
915  This->pixelformat = &GUID_WICPixelFormatUndefined;
916  FIXME("Huffman 1D compression is unsupported\n");
917  break;
918  }
919  This->bitsperpixel = This->bih.bV5BitCount;
920  for (format = bitfields_formats; format->bitcount; format++)
921  {
922  if ((format->bitcount == This->bih.bV5BitCount) &&
923  (format->redmask == This->bih.bV5RedMask) &&
924  (format->greenmask == This->bih.bV5GreenMask) &&
925  (format->bluemask == This->bih.bV5BlueMask) &&
926  (format->alphamask == This->bih.bV5AlphaMask))
927  {
928  This->read_data_func = format->read_data_func;
929  This->pixelformat = format->pixelformat;
930  break;
931  }
932  }
933  if (!format->bitcount)
934  {
936  This->pixelformat = &GUID_WICPixelFormatUndefined;
937  FIXME("unsupported bitfields type depth=%i red=%x green=%x blue=%x alpha=%x\n",
938  This->bih.bV5BitCount, This->bih.bV5RedMask, This->bih.bV5GreenMask, This->bih.bV5BlueMask, This->bih.bV5AlphaMask);
939  }
940  break;
941  }
942  default:
943  This->bitsperpixel = 0;
945  This->pixelformat = &GUID_WICPixelFormatUndefined;
946  FIXME("unsupported bitmap type header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
947  break;
948  }
949  }
950 
951  if (This->packed)
952  {
953  /* In a packed DIB, the image follows the palette. */
954  ULONG palette_count, palette_size;
955  if (This->bih.bV5ClrUsed)
956  palette_count = This->bih.bV5ClrUsed;
957  else if (This->bih.bV5BitCount <= 8)
958  palette_count = 1 << This->bih.bV5BitCount;
959  else
960  palette_count = 0;
961  if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
962  palette_size = sizeof(RGBTRIPLE) * palette_count;
963  else
964  palette_size = sizeof(RGBQUAD) * palette_count;
965  This->image_offset = This->palette_offset + palette_size;
966  }
967 
968  This->initialized = TRUE;
969 
970  return S_OK;
971 }
972 
974  void **ppv)
975 {
977  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
978 
979  if (!ppv) return E_INVALIDARG;
980 
981  if (IsEqualIID(&IID_IUnknown, iid) ||
982  IsEqualIID(&IID_IWICBitmapDecoder, iid))
983  {
984  *ppv = &This->IWICBitmapDecoder_iface;
985  }
986  else
987  {
988  *ppv = NULL;
989  return E_NOINTERFACE;
990  }
991 
992  IUnknown_AddRef((IUnknown*)*ppv);
993  return S_OK;
994 }
995 
997 {
999  ULONG ref = InterlockedIncrement(&This->ref);
1000 
1001  TRACE("(%p) refcount=%u\n", iface, ref);
1002 
1003  return ref;
1004 }
1005 
1007 {
1008  BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
1009  ULONG ref = InterlockedDecrement(&This->ref);
1010 
1011  TRACE("(%p) refcount=%u\n", iface, ref);
1012 
1013  if (ref == 0)
1014  {
1015  if (This->stream) IStream_Release(This->stream);
1016  HeapFree(GetProcessHeap(), 0, This->imagedata);
1017  This->lock.DebugInfo->Spare[0] = 0;
1018  DeleteCriticalSection(&This->lock);
1019  HeapFree(GetProcessHeap(), 0, This);
1020  }
1021 
1022  return ref;
1023 }
1024 
1026  DWORD *capability)
1027 {
1028  HRESULT hr;
1029  BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
1030 
1031  TRACE("(%p,%p,%p)\n", iface, stream, capability);
1032 
1033  if (!stream || !capability) return E_INVALIDARG;
1034 
1035  hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
1036  if (hr != S_OK) return hr;
1037 
1039  return S_OK;
1040 }
1041 
1043  WICDecodeOptions cacheOptions)
1044 {
1045  HRESULT hr;
1046  BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
1047 
1048  EnterCriticalSection(&This->lock);
1049  hr = BmpDecoder_ReadHeaders(This, pIStream);
1050 
1051  if (SUCCEEDED(hr))
1052  {
1053  This->stream = pIStream;
1054  IStream_AddRef(pIStream);
1055  }
1056  LeaveCriticalSection(&This->lock);
1057 
1058  return hr;
1059 }
1060 
1062  GUID *pguidContainerFormat)
1063 {
1064  memcpy(pguidContainerFormat, &GUID_ContainerFormatBmp, sizeof(GUID));
1065  return S_OK;
1066 }
1067 
1069  IWICBitmapDecoderInfo **ppIDecoderInfo)
1070 {
1071  TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
1072 
1073  return get_decoder_info(&CLSID_WICBmpDecoder, ppIDecoderInfo);
1074 }
1075 
1077  IWICPalette *pIPalette)
1078 {
1079  TRACE("(%p,%p)\n", iface, pIPalette);
1080 
1082 }
1083 
1085  IWICMetadataQueryReader **ppIMetadataQueryReader)
1086 {
1087  TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
1089 }
1090 
1092  IWICBitmapSource **ppIBitmapSource)
1093 {
1094  TRACE("(%p,%p)\n", iface, ppIBitmapSource);
1096 }
1097 
1099  UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
1100 {
1101  TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
1103 }
1104 
1106  IWICBitmapSource **ppIThumbnail)
1107 {
1108  TRACE("(%p,%p)\n", iface, ppIThumbnail);
1110 }
1111 
1113  UINT *pCount)
1114 {
1115  if (!pCount) return E_INVALIDARG;
1116 
1117  *pCount = 1;
1118  return S_OK;
1119 }
1120 
1122  UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
1123 {
1124  BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
1125 
1126  if (index != 0) return E_INVALIDARG;
1127 
1128  if (!This->stream) return WINCODEC_ERR_FRAMEMISSING;
1129 
1130  *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;
1131  IWICBitmapDecoder_AddRef(iface);
1132 
1133  return S_OK;
1134 }
1135 
1136 static const IWICBitmapDecoderVtbl BmpDecoder_Vtbl = {
1151 };
1152 
1153 static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecoder)
1154 {
1155  BmpDecoder *This;
1156 
1157  This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder));
1158  if (!This) return E_OUTOFMEMORY;
1159 
1160  This->IWICBitmapDecoder_iface.lpVtbl = &BmpDecoder_Vtbl;
1162  This->ref = 1;
1163  This->initialized = FALSE;
1164  This->stream = NULL;
1165  This->imagedata = NULL;
1167  This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
1168  This->packed = packed;
1169  This->icoframe = icoframe;
1170 
1171  *ppDecoder = This;
1172 
1173  return S_OK;
1174 }
1175 
1176 static HRESULT BmpDecoder_Construct(int packed, int icoframe, REFIID iid, void** ppv)
1177 {
1178  BmpDecoder *This;
1179  HRESULT ret;
1180 
1181  TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
1182 
1183  *ppv = NULL;
1184 
1185  ret = BmpDecoder_Create(packed, icoframe, &This);
1186  if (FAILED(ret)) return ret;
1187 
1188  ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
1189  IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
1190 
1191  return ret;
1192 }
1193 
1195 {
1196  return BmpDecoder_Construct(FALSE, FALSE, iid, ppv);
1197 }
1198 
1200 {
1201  return BmpDecoder_Construct(TRUE, FALSE, iid, ppv);
1202 }
1203 
1205 {
1206  return BmpDecoder_Create(TRUE, TRUE, ppDecoder);
1207 }
1208 
1210 {
1211  *ppDecoder = &This->IWICBitmapDecoder_iface;
1212 }
1213 
1214 /* Return the offset where the mask of an icon might be, or 0 for failure. */
1215 void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown)
1216 {
1217  assert(This->stream != NULL);
1218 
1220  {
1221  /* RGB or BITFIELDS data */
1222  ULONG width, height, bytesperrow, datasize;
1223  IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height);
1224  bytesperrow = (((width * This->bitsperpixel)+31)/32)*4;
1225  datasize = bytesperrow * height;
1226  *mask_offset = This->image_offset + datasize;
1227  }
1228  else
1229  *mask_offset = 0;
1230 
1231  *topdown = This->stride > 0;
1232 }
static HRESULT BmpFrameDecode_ReadRGB8(BmpDecoder *This)
Definition: bmpdecode.c:420
static HRESULT WINAPI BmpFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: bmpdecode.c:342
#define abs(i)
Definition: fconv.c:206
BYTE rgbtBlue
Definition: wingdi.h:1415
int packed
Definition: bmpdecode.c:79
unsigned short WORD
Definition: ntddk_ex.h:93
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat)
Definition: bmpdecode.c:152
const GUID IID_IUnknown
static HRESULT ReadByte(IStream *stream, BYTE *buffer, ULONG buffer_size, ULONG *cursor, ULONG *bytesread, BYTE *result)
Definition: bmpdecode.c:441
HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder)
Definition: bmpdecode.c:1204
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
Definition: bmpdecode.c:1006
CRITICAL_SECTION lock
Definition: bmpdecode.c:78
DWORD bc2Compression
Definition: bmpdecode.c:44
static HRESULT WINAPI BmpDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, IWICBitmapDecoderInfo **ppIDecoderInfo)
Definition: bmpdecode.c:1068
void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown)
Definition: bmpdecode.c:1215
HRESULT DibDecoder_CreateInstance(REFIID iid, void **ppv)
Definition: bmpdecode.c:1199
ReadDataFunc read_data_func
Definition: bmpdecode.c:74
static HRESULT WINAPI BmpDecoder_GetFrameCount(IWICBitmapDecoder *iface, UINT *pCount)
Definition: bmpdecode.c:1112
#define WARN(fmt,...)
Definition: debug.h:111
static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
Definition: bmpdecode.c:118
GLintptr offset
Definition: glext.h:5920
REFIID LPVOID * ppv
Definition: atlbase.h:39
DWORD bc2HalftoneSize2
Definition: bmpdecode.c:56
#define assert(x)
Definition: debug.h:53
GLuint buffer
Definition: glext.h:5915
GLuint GLuint end
Definition: gl.h:1545
const WICPixelFormatGUID * pixelformat
Definition: bmpdecode.c:738
HRESULT BmpDecoder_CreateInstance(REFIID iid, void **ppv)
Definition: bmpdecode.c:1194
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
ULONG image_offset
Definition: bmpdecode.c:70
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecoder)
Definition: bmpdecode.c:1153
#define DWORD
Definition: msvc.h:34
int32_t INT
Definition: typedefs.h:56
Definition: send.c:47
#define BI_BITFIELDS
Definition: mmreg.h:507
DWORD DWORD
Definition: winlogon.h:84
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
Definition: bmpdecode.c:125
while(1)
Definition: macro.lex.yy.c:743
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
static HRESULT WINAPI BmpDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: bmpdecode.c:1084
static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder *This)
Definition: bmpdecode.c:587
GLuint color
Definition: glext.h:6243
void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder)
Definition: bmpdecode.c:1209
static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder *This)
Definition: bmpdecode.c:363
IStream * stream
Definition: bmpdecode.c:68
GLenum GLint ref
Definition: glext.h:6028
static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
Definition: bmpdecode.c:1121
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
static const struct bitfields_format bitfields_formats[]
Definition: bmpdecode.c:742
#define WINCODEC_ERR_PALETTEUNAVAILABLE
Definition: winerror.h:3282
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI BmpDecoder_GetThumbnail(IWICBitmapDecoder *iface, IWICBitmapSource **ppIThumbnail)
Definition: bmpdecode.c:1105
ReadDataFunc read_data_func
Definition: bmpdecode.c:739
static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, double *pDpiY)
Definition: bmpdecode.c:163
struct tagRGBTRIPLE RGBTRIPLE
GLuint index
Definition: glext.h:6031
#define debugstr_guid
Definition: kernel32.h:35
IWICBitmapDecoder IWICBitmapDecoder_iface
Definition: bmpdecode.c:64
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
LONG ref
Definition: bmpdecode.c:66
static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY)
Definition: bmpdecode.c:196
DWORD bc2HalftoneSize1
Definition: bmpdecode.c:55
struct tagRGBQUAD RGBQUAD
BITMAPV5HEADER bih
Definition: bmpdecode.c:71
DWORD bc2ColorSpace
Definition: bmpdecode.c:57
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
int bitsperpixel
Definition: bmpdecode.c:73
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
GLint GLint GLsizei width
Definition: gl.h:1546
if(!(yy_init))
Definition: macro.lex.yy.c:717
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static BmpDecoder * impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
Definition: bmpdecode.c:83
struct tagBITMAPCOREHEADER BITMAPCOREHEADER
GLuint GLuint GLsizei count
Definition: gl.h:1545
const WICPixelFormatGUID * pixelformat
Definition: bmpdecode.c:72
#define WINCODEC_ERR_CODECNOTHUMBNAIL
Definition: winerror.h:3281
ULONG palette_offset
Definition: bmpdecode.c:69
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:859
static HRESULT BmpDecoder_ReadHeaders(BmpDecoder *This, IStream *stream)
Definition: bmpdecode.c:765
static HRESULT WINAPI BmpFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: bmpdecode.c:349
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
static const IWICBitmapDecoderVtbl BmpDecoder_Vtbl
Definition: bmpdecode.c:1136
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface
Definition: bmpdecode.c:65
int ret
HRESULT(* ReadDataFunc)(BmpDecoder *This)
Definition: bmpdecode.c:61
BOOL initialized
Definition: bmpdecode.c:67
#define WINCODEC_ERR_FRAMEMISSING
Definition: winerror.h:3291
#define index(s, c)
Definition: various.h:29
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static unsigned int palette_size(DWORD flags)
Definition: palette.c:241
static HRESULT WINAPI BmpDecoder_GetColorContexts(IWICBitmapDecoder *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: bmpdecode.c:1098
static HRESULT BmpDecoder_Construct(int packed, int icoframe, REFIID iid, void **ppv)
Definition: bmpdecode.c:1176
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
Definition: winerror.h:3298
#define WINAPI
Definition: msvc.h:20
static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, WICDecodeOptions cacheOptions)
Definition: bmpdecode.c:1042
static HPALETTE palette
Definition: clipboard.c:1345
static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder *This)
Definition: bmpdecode.c:463
static HRESULT WINAPI BmpDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette *pIPalette)
Definition: bmpdecode.c:1076
unsigned char BYTE
Definition: ntddk_ex.h:96
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size, const struct pixel_format_desc *format) DECLSPEC_HIDDEN
Definition: surface.c:1601
static HRESULT BmpFrameDecode_ReadUnsupported(BmpDecoder *This)
Definition: bmpdecode.c:727
WICDecodeOptions
Definition: wincodec.idl:27
static HRESULT WINAPI BmpDecoder_GetPreview(IWICBitmapDecoder *iface, IWICBitmapSource **ppIBitmapSource)
Definition: bmpdecode.c:1091
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3271
#define S_OK
Definition: intsafe.h:59
static GpStatus get_decoder_info(IStream *stream, const struct image_codec **result)
Definition: image.c:4196
#define DWORD_PTR
Definition: generated.c:24
static HRESULT WINAPI BmpDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, void **ppv)
Definition: bmpdecode.c:973
#define InterlockedIncrement
Definition: armddk.h:53
const char cursor[]
Definition: icontest.c:13
INT INT dy
Definition: msvc.h:65
static BmpDecoder * impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
Definition: bmpdecode.c:88
static HRESULT WINAPI BmpDecoder_GetContainerFormat(IWICBitmapDecoder *iface, GUID *pguidContainerFormat)
Definition: bmpdecode.c:1061
int icoframe
Definition: bmpdecode.c:80
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight)
Definition: bmpdecode.c:132
#define min(a, b)
Definition: monoChain.cc:55
BYTE rgbtRed
Definition: wingdi.h:1417
unsigned int UINT
Definition: ndis.h:50
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv)
Definition: bmpdecode.c:93
#define BI_RLE4
Definition: precomp.h:36
static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette)
Definition: bmpdecode.c:205
BYTE * imagedatastart
Definition: bmpdecode.c:77
static WCHAR escape[]
Definition: url.c:36
#define HRESULT
Definition: msvc.h:21
unsigned int ULONG
Definition: retypes.h:1
static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl
Definition: bmpdecode.c:751
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
Definition: main.c:212
static ULONG WINAPI BmpDecoder_AddRef(IWICBitmapDecoder *iface)
Definition: bmpdecode.c:996
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static HRESULT WINAPI BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, IWICBitmapSource **ppIThumbnail)
Definition: bmpdecode.c:356
static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, DWORD *capability)
Definition: bmpdecode.c:1025
DWORD bc2SizeImage
Definition: bmpdecode.c:45
INT stride
Definition: bmpdecode.c:75
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs)
static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
Definition: bmpdecode.c:318
INT INT y
Definition: msvc.h:62
#define BI_RLE8
Definition: wingdi.h:35
GLuint64EXT * result
Definition: glext.h:11304
UINT32 WICColor
Definition: wincodec.idl:250
#define BI_RGB
Definition: precomp.h:35
BYTE * imagedata
Definition: bmpdecode.c:76
#define HeapFree(x, y, z)
Definition: compat.h:394
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
DWORD bc2ClrImportant
Definition: bmpdecode.c:49
#define SUCCEEDED(hr)
Definition: intsafe.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:852
INT x
Definition: msvc.h:62
INT dx
Definition: msvc.h:65