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