ReactOS  0.4.14-dev-323-g6fe6a88
gifformat.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009 Vincent Povirk for CodeWeavers
3  * Copyright 2012,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 
24 #define COBJMACROS
25 #define NONAMELESSUNION
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "objbase.h"
30 
31 #include "ungif.h"
32 
33 #include "wincodecs_private.h"
34 
35 #include "wine/debug.h"
36 
37 #ifdef __REACTOS__
38 #include <ole2.h>
39 #endif
40 
42 
43 #include "pshpack1.h"
44 
46 {
47  char signature[6];
51  /* global_color_table_flag : 1;
52  * color_resolution : 3;
53  * sort_flag : 1;
54  * global_color_table_size : 3;
55  */
58 };
59 
61 {
67  /* local_color_table_flag : 1;
68  * interlace_flag : 1;
69  * sort_flag : 1;
70  * reserved : 2;
71  * local_color_table_size : 3;
72  */
73 };
74 
75 #include "poppack.h"
76 
77 static LPWSTR strdupAtoW(const char *src)
78 {
79  int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
80  LPWSTR dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
81  if (dst) MultiByteToWideChar(CP_ACP, 0, src, -1, dst, len);
82  return dst;
83 }
84 
87 {
88  struct logical_screen_descriptor lsd_data;
89  HRESULT hr;
90  ULONG bytesread, i;
92 
93  *items = NULL;
94  *count = 0;
95 
96  hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread);
97  if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK;
98 
100  if (!result) return E_OUTOFMEMORY;
101 
102  for (i = 0; i < 9; i++)
103  {
104  PropVariantInit(&result[i].schema);
105  PropVariantInit(&result[i].id);
106  PropVariantInit(&result[i].value);
107  }
108 
109  result[0].id.vt = VT_LPWSTR;
110  result[0].id.u.pwszVal = strdupAtoW("Signature");
111  result[0].value.vt = VT_UI1|VT_VECTOR;
112  result[0].value.u.caub.cElems = sizeof(lsd_data.signature);
113  result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(lsd_data.signature));
114  memcpy(result[0].value.u.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature));
115 
116  result[1].id.vt = VT_LPWSTR;
117  result[1].id.u.pwszVal = strdupAtoW("Width");
118  result[1].value.vt = VT_UI2;
119  result[1].value.u.uiVal = lsd_data.width;
120 
121  result[2].id.vt = VT_LPWSTR;
122  result[2].id.u.pwszVal = strdupAtoW("Height");
123  result[2].value.vt = VT_UI2;
124  result[2].value.u.uiVal = lsd_data.height;
125 
126  result[3].id.vt = VT_LPWSTR;
127  result[3].id.u.pwszVal = strdupAtoW("GlobalColorTableFlag");
128  result[3].value.vt = VT_BOOL;
129  result[3].value.u.boolVal = (lsd_data.packed >> 7) & 1;
130 
131  result[4].id.vt = VT_LPWSTR;
132  result[4].id.u.pwszVal = strdupAtoW("ColorResolution");
133  result[4].value.vt = VT_UI1;
134  result[4].value.u.bVal = (lsd_data.packed >> 4) & 7;
135 
136  result[5].id.vt = VT_LPWSTR;
137  result[5].id.u.pwszVal = strdupAtoW("SortFlag");
138  result[5].value.vt = VT_BOOL;
139  result[5].value.u.boolVal = (lsd_data.packed >> 3) & 1;
140 
141  result[6].id.vt = VT_LPWSTR;
142  result[6].id.u.pwszVal = strdupAtoW("GlobalColorTableSize");
143  result[6].value.vt = VT_UI1;
144  result[6].value.u.bVal = lsd_data.packed & 7;
145 
146  result[7].id.vt = VT_LPWSTR;
147  result[7].id.u.pwszVal = strdupAtoW("BackgroundColorIndex");
148  result[7].value.vt = VT_UI1;
149  result[7].value.u.bVal = lsd_data.background_color_index;
150 
151  result[8].id.vt = VT_LPWSTR;
152  result[8].id.u.pwszVal = strdupAtoW("PixelAspectRatio");
153  result[8].value.vt = VT_UI1;
154  result[8].value.u.bVal = lsd_data.pixel_aspect_ratio;
155 
156  *items = result;
157  *count = 9;
158 
159  return S_OK;
160 }
161 
163  0,
164  &CLSID_WICLSDMetadataReader,
166 };
167 
169 {
171 }
172 
175 {
176  struct image_descriptor imd_data;
177  HRESULT hr;
178  ULONG bytesread, i;
180 
181  *items = NULL;
182  *count = 0;
183 
184  hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread);
185  if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK;
186 
188  if (!result) return E_OUTOFMEMORY;
189 
190  for (i = 0; i < 8; i++)
191  {
192  PropVariantInit(&result[i].schema);
193  PropVariantInit(&result[i].id);
194  PropVariantInit(&result[i].value);
195  }
196 
197  result[0].id.vt = VT_LPWSTR;
198  result[0].id.u.pwszVal = strdupAtoW("Left");
199  result[0].value.vt = VT_UI2;
200  result[0].value.u.uiVal = imd_data.left;
201 
202  result[1].id.vt = VT_LPWSTR;
203  result[1].id.u.pwszVal = strdupAtoW("Top");
204  result[1].value.vt = VT_UI2;
205  result[1].value.u.uiVal = imd_data.top;
206 
207  result[2].id.vt = VT_LPWSTR;
208  result[2].id.u.pwszVal = strdupAtoW("Width");
209  result[2].value.vt = VT_UI2;
210  result[2].value.u.uiVal = imd_data.width;
211 
212  result[3].id.vt = VT_LPWSTR;
213  result[3].id.u.pwszVal = strdupAtoW("Height");
214  result[3].value.vt = VT_UI2;
215  result[3].value.u.uiVal = imd_data.height;
216 
217  result[4].id.vt = VT_LPWSTR;
218  result[4].id.u.pwszVal = strdupAtoW("LocalColorTableFlag");
219  result[4].value.vt = VT_BOOL;
220  result[4].value.u.boolVal = (imd_data.packed >> 7) & 1;
221 
222  result[5].id.vt = VT_LPWSTR;
223  result[5].id.u.pwszVal = strdupAtoW("InterlaceFlag");
224  result[5].value.vt = VT_BOOL;
225  result[5].value.u.boolVal = (imd_data.packed >> 6) & 1;
226 
227  result[6].id.vt = VT_LPWSTR;
228  result[6].id.u.pwszVal = strdupAtoW("SortFlag");
229  result[6].value.vt = VT_BOOL;
230  result[6].value.u.boolVal = (imd_data.packed >> 5) & 1;
231 
232  result[7].id.vt = VT_LPWSTR;
233  result[7].id.u.pwszVal = strdupAtoW("LocalColorTableSize");
234  result[7].value.vt = VT_UI1;
235  result[7].value.u.bVal = imd_data.packed & 7;
236 
237  *items = result;
238  *count = 8;
239 
240  return S_OK;
241 }
242 
244  0,
245  &CLSID_WICIMDMetadataReader,
247 };
248 
250 {
252 }
253 
256 {
257 #include "pshpack1.h"
258  struct graphic_control_extension
259  {
260  BYTE packed;
261  /* reservred: 3;
262  * disposal : 3;
263  * user_input_flag : 1;
264  * transparency_flag : 1;
265  */
266  USHORT delay;
267  BYTE transparent_color_index;
268  } gce_data;
269 #include "poppack.h"
270  HRESULT hr;
271  ULONG bytesread, i;
273 
274  *items = NULL;
275  *count = 0;
276 
277  hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread);
278  if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK;
279 
281  if (!result) return E_OUTOFMEMORY;
282 
283  for (i = 0; i < 5; i++)
284  {
285  PropVariantInit(&result[i].schema);
286  PropVariantInit(&result[i].id);
287  PropVariantInit(&result[i].value);
288  }
289 
290  result[0].id.vt = VT_LPWSTR;
291  result[0].id.u.pwszVal = strdupAtoW("Disposal");
292  result[0].value.vt = VT_UI1;
293  result[0].value.u.bVal = (gce_data.packed >> 2) & 7;
294 
295  result[1].id.vt = VT_LPWSTR;
296  result[1].id.u.pwszVal = strdupAtoW("UserInputFlag");
297  result[1].value.vt = VT_BOOL;
298  result[1].value.u.boolVal = (gce_data.packed >> 1) & 1;
299 
300  result[2].id.vt = VT_LPWSTR;
301  result[2].id.u.pwszVal = strdupAtoW("TransparencyFlag");
302  result[2].value.vt = VT_BOOL;
303  result[2].value.u.boolVal = gce_data.packed & 1;
304 
305  result[3].id.vt = VT_LPWSTR;
306  result[3].id.u.pwszVal = strdupAtoW("Delay");
307  result[3].value.vt = VT_UI2;
308  result[3].value.u.uiVal = gce_data.delay;
309 
310  result[4].id.vt = VT_LPWSTR;
311  result[4].id.u.pwszVal = strdupAtoW("TransparentColorIndex");
312  result[4].value.vt = VT_UI1;
313  result[4].value.u.bVal = gce_data.transparent_color_index;
314 
315  *items = result;
316  *count = 5;
317 
318  return S_OK;
319 }
320 
322  0,
323  &CLSID_WICGCEMetadataReader,
325 };
326 
328 {
330 }
331 
334 {
335 #include "pshpack1.h"
336  struct application_extension
337  {
338  BYTE extension_introducer;
339  BYTE extension_label;
341  BYTE application[11];
342  } ape_data;
343 #include "poppack.h"
344  HRESULT hr;
345  ULONG bytesread, data_size, i;
347  BYTE subblock_size;
348  BYTE *data;
349 
350  *items = NULL;
351  *count = 0;
352 
353  hr = IStream_Read(stream, &ape_data, sizeof(ape_data), &bytesread);
354  if (FAILED(hr) || bytesread != sizeof(ape_data)) return S_OK;
355  if (ape_data.extension_introducer != 0x21 ||
356  ape_data.extension_label != APPLICATION_EXT_FUNC_CODE ||
357  ape_data.block_size != 11)
358  return S_OK;
359 
360  data = NULL;
361  data_size = 0;
362 
363  for (;;)
364  {
365  hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread);
366  if (FAILED(hr) || bytesread != sizeof(subblock_size))
367  {
369  return S_OK;
370  }
371  if (!subblock_size) break;
372 
373  if (!data)
374  data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1);
375  else
376  {
377  BYTE *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1);
378  if (!new_data)
379  {
381  return S_OK;
382  }
383  data = new_data;
384  }
385  data[data_size] = subblock_size;
386  hr = IStream_Read(stream, data + data_size + 1, subblock_size, &bytesread);
387  if (FAILED(hr) || bytesread != subblock_size)
388  {
390  return S_OK;
391  }
392  data_size += subblock_size + 1;
393  }
394 
396  if (!result)
397  {
399  return E_OUTOFMEMORY;
400  }
401 
402  for (i = 0; i < 2; i++)
403  {
404  PropVariantInit(&result[i].schema);
405  PropVariantInit(&result[i].id);
406  PropVariantInit(&result[i].value);
407  }
408 
409  result[0].id.vt = VT_LPWSTR;
410  result[0].id.u.pwszVal = strdupAtoW("Application");
411  result[0].value.vt = VT_UI1|VT_VECTOR;
412  result[0].value.u.caub.cElems = sizeof(ape_data.application);
413  result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(ape_data.application));
414  memcpy(result[0].value.u.caub.pElems, ape_data.application, sizeof(ape_data.application));
415 
416  result[1].id.vt = VT_LPWSTR;
417  result[1].id.u.pwszVal = strdupAtoW("Data");
418  result[1].value.vt = VT_UI1|VT_VECTOR;
419  result[1].value.u.caub.cElems = data_size;
420  result[1].value.u.caub.pElems = data;
421 
422  *items = result;
423  *count = 2;
424 
425  return S_OK;
426 }
427 
429  0,
430  &CLSID_WICAPEMetadataReader,
432 };
433 
435 {
437 }
438 
441 {
442 #include "pshpack1.h"
443  struct gif_extension
444  {
445  BYTE extension_introducer;
446  BYTE extension_label;
447  } ext_data;
448 #include "poppack.h"
449  HRESULT hr;
450  ULONG bytesread, data_size;
452  BYTE subblock_size;
453  char *data;
454 
455  *items = NULL;
456  *count = 0;
457 
458  hr = IStream_Read(stream, &ext_data, sizeof(ext_data), &bytesread);
459  if (FAILED(hr) || bytesread != sizeof(ext_data)) return S_OK;
460  if (ext_data.extension_introducer != 0x21 ||
461  ext_data.extension_label != COMMENT_EXT_FUNC_CODE)
462  return S_OK;
463 
464  data = NULL;
465  data_size = 0;
466 
467  for (;;)
468  {
469  hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread);
470  if (FAILED(hr) || bytesread != sizeof(subblock_size))
471  {
473  return S_OK;
474  }
475  if (!subblock_size) break;
476 
477  if (!data)
478  data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1);
479  else
480  {
481  char *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1);
482  if (!new_data)
483  {
485  return S_OK;
486  }
487  data = new_data;
488  }
489  hr = IStream_Read(stream, data + data_size, subblock_size, &bytesread);
490  if (FAILED(hr) || bytesread != subblock_size)
491  {
493  return S_OK;
494  }
495  data_size += subblock_size;
496  }
497 
498  data[data_size] = 0;
499 
501  if (!result)
502  {
504  return E_OUTOFMEMORY;
505  }
506 
507  PropVariantInit(&result->schema);
508  PropVariantInit(&result->id);
509  PropVariantInit(&result->value);
510 
511  result->id.vt = VT_LPWSTR;
512  result->id.u.pwszVal = strdupAtoW("TextEntry");
513  result->value.vt = VT_LPSTR;
514  result->value.u.pszVal = data;
515 
516  *items = result;
517  *count = 1;
518 
519  return S_OK;
520 }
521 
523  0,
524  &CLSID_WICGifCommentMetadataReader,
526 };
527 
529 {
531 }
532 
533 static IStream *create_stream(const void *data, int data_size)
534 {
535  HRESULT hr;
536  IStream *stream;
537  HGLOBAL hdata;
538  void *locked_data;
539 
540  hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
541  if (!hdata) return NULL;
542 
543  locked_data = GlobalLock(hdata);
544  memcpy(locked_data, data, data_size);
545  GlobalUnlock(hdata);
546 
547  hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
548  return FAILED(hr) ? NULL : stream;
549 }
550 
551 static HRESULT create_metadata_reader(const void *data, int data_size,
552  class_constructor constructor,
554 {
555  HRESULT hr;
556  IWICMetadataReader *metadata_reader;
557  IWICPersistStream *persist;
558  IStream *stream;
559 
560  /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
561 
562  hr = constructor(&IID_IWICMetadataReader, (void**)&metadata_reader);
563  if (FAILED(hr)) return hr;
564 
565  hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
566  if (FAILED(hr))
567  {
568  IWICMetadataReader_Release(metadata_reader);
569  return hr;
570  }
571 
572  stream = create_stream(data, data_size);
573  IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionDefault);
574  IStream_Release(stream);
575 
576  IWICPersistStream_Release(persist);
577 
578  *reader = metadata_reader;
579  return S_OK;
580 }
581 
582 typedef struct {
586  BYTE LSD_data[13]; /* Logical Screen Descriptor */
592 } GifDecoder;
593 
594 typedef struct {
601 
603 {
604  return CONTAINING_RECORD(iface, GifDecoder, IWICBitmapDecoder_iface);
605 }
606 
608 {
609  return CONTAINING_RECORD(iface, GifDecoder, IWICMetadataBlockReader_iface);
610 }
611 
613 {
614  return CONTAINING_RECORD(iface, GifFrameDecode, IWICBitmapFrameDecode_iface);
615 }
616 
618 {
619  return CONTAINING_RECORD(iface, GifFrameDecode, IWICMetadataBlockReader_iface);
620 }
621 
623  void **ppv)
624 {
626  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
627 
628  if (!ppv) return E_INVALIDARG;
629 
630  if (IsEqualIID(&IID_IUnknown, iid) ||
631  IsEqualIID(&IID_IWICBitmapSource, iid) ||
632  IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
633  {
634  *ppv = &This->IWICBitmapFrameDecode_iface;
635  }
636  else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
637  {
638  *ppv = &This->IWICMetadataBlockReader_iface;
639  }
640  else
641  {
642  *ppv = NULL;
643  return E_NOINTERFACE;
644  }
645 
646  IUnknown_AddRef((IUnknown*)*ppv);
647  return S_OK;
648 }
649 
651 {
654 
655  TRACE("(%p) refcount=%u\n", iface, ref);
656 
657  return ref;
658 }
659 
661 {
664 
665  TRACE("(%p) refcount=%u\n", iface, ref);
666 
667  if (ref == 0)
668  {
669  IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface);
671  }
672 
673  return ref;
674 }
675 
677  UINT *puiWidth, UINT *puiHeight)
678 {
680  TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
681 
682  *puiWidth = This->frame->ImageDesc.Width;
683  *puiHeight = This->frame->ImageDesc.Height;
684 
685  return S_OK;
686 }
687 
689  WICPixelFormatGUID *pPixelFormat)
690 {
691  memcpy(pPixelFormat, &GUID_WICPixelFormat8bppIndexed, sizeof(GUID));
692 
693  return S_OK;
694 }
695 
697  double *pDpiX, double *pDpiY)
698 {
700  const GifWord aspect_word = This->parent->gif->SAspectRatio;
701  const double aspect = (aspect_word > 0) ? ((aspect_word + 15.0) / 64.0) : 1.0;
702  TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
703 
704  *pDpiX = 96.0 / aspect;
705  *pDpiY = 96.0;
706 
707  return S_OK;
708 }
709 
711  IWICPalette *pIPalette)
712 {
714  WICColor colors[256];
715  ColorMapObject *cm = This->frame->ImageDesc.ColorMap;
716  int i, trans;
717  ExtensionBlock *eb;
718  TRACE("(%p,%p)\n", iface, pIPalette);
719 
720  if (!cm) cm = This->parent->gif->SColorMap;
721 
722  if (cm->ColorCount > 256)
723  {
724  ERR("GIF contains %i colors???\n", cm->ColorCount);
725  return E_FAIL;
726  }
727 
728  for (i = 0; i < cm->ColorCount; i++) {
729  colors[i] = 0xff000000| /* alpha */
730  cm->Colors[i].Red << 16|
731  cm->Colors[i].Green << 8|
732  cm->Colors[i].Blue;
733  }
734 
735  /* look for the transparent color extension */
736  for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; ++i) {
737  eb = This->frame->Extensions.ExtensionBlocks + i;
738  if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8) {
739  if (eb->Bytes[3] & 1) {
740  trans = (unsigned char)eb->Bytes[6];
741  colors[trans] &= 0xffffff; /* set alpha to 0 */
742  break;
743  }
744  }
745  }
746 
747  return IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount);
748 }
749 
750 static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer,
751  UINT srcwidth, UINT srcheight, INT srcstride, const WICRect *rc,
752  UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
753 {
754  UINT row_offset; /* number of bytes into the source rows where the data starts */
755  const BYTE *src;
756  BYTE *dst;
757  UINT y;
758  WICRect rect;
759 
760  if (!rc)
761  {
762  rect.X = 0;
763  rect.Y = 0;
764  rect.Width = srcwidth;
765  rect.Height = srcheight;
766  rc = &rect;
767  }
768  else
769  {
770  if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
771  return E_INVALIDARG;
772  }
773 
774  if (dststride < rc->Width)
775  return E_INVALIDARG;
776 
777  if ((dststride * rc->Height) > dstbuffersize)
778  return E_INVALIDARG;
779 
780  row_offset = rc->X;
781 
782  dst = dstbuffer;
783  for (y=rc->Y; y-rc->Y < rc->Height; y++)
784  {
785  if (y%8 == 0)
786  src = srcbuffer + srcstride * (y/8);
787  else if (y%4 == 0)
788  src = srcbuffer + srcstride * ((srcheight+7)/8 + y/8);
789  else if (y%2 == 0)
790  src = srcbuffer + srcstride * ((srcheight+3)/4 + y/4);
791  else /* y%2 == 1 */
792  src = srcbuffer + srcstride * ((srcheight+1)/2 + y/2);
793  src += row_offset;
794  memcpy(dst, src, rc->Width);
795  dst += dststride;
796  }
797  return S_OK;
798 }
799 
801  const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
802 {
804  TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
805 
806  if (This->frame->ImageDesc.Interlace)
807  {
808  return copy_interlaced_pixels(This->frame->RasterBits, This->frame->ImageDesc.Width,
809  This->frame->ImageDesc.Height, This->frame->ImageDesc.Width,
810  prc, cbStride, cbBufferSize, pbBuffer);
811  }
812  else
813  {
814  return copy_pixels(8, This->frame->RasterBits, This->frame->ImageDesc.Width,
815  This->frame->ImageDesc.Height, This->frame->ImageDesc.Width,
816  prc, cbStride, cbBufferSize, pbBuffer);
817  }
818 }
819 
821  IWICMetadataQueryReader **ppIMetadataQueryReader)
822 {
824 
825  TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
826 
827  if (!ppIMetadataQueryReader)
828  return E_INVALIDARG;
829 
830  return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader);
831 }
832 
834  UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
835 {
836  TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
838 }
839 
841  IWICBitmapSource **ppIThumbnail)
842 {
843  TRACE("(%p,%p)\n", iface, ppIThumbnail);
845 }
846 
847 static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl = {
859 };
860 
862  REFIID iid, void **ppv)
863 {
865  return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv);
866 }
867 
869 {
871  return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface);
872 }
873 
875 {
877  return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface);
878 }
879 
881  GUID *guid)
882 {
883  TRACE("(%p,%p)\n", iface, guid);
884 
885  if (!guid) return E_INVALIDARG;
886 
887  *guid = GUID_ContainerFormatGif;
888  return S_OK;
889 }
890 
892  UINT *count)
893 {
895 
896  TRACE("%p,%p\n", iface, count);
897 
898  if (!count) return E_INVALIDARG;
899 
900  *count = This->frame->Extensions.ExtensionBlockCount + 1;
901  return S_OK;
902 }
903 
905 {
906  HRESULT hr;
907  IWICMetadataReader *metadata_reader;
908  IWICPersistStream *persist;
909  IStream *stream;
910  struct image_descriptor IMD_data;
911 
912  /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
913 
914  hr = IMDReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader);
915  if (FAILED(hr)) return hr;
916 
917  hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
918  if (FAILED(hr))
919  {
920  IWICMetadataReader_Release(metadata_reader);
921  return hr;
922  }
923 
924  /* recreate IMD structure from GIF decoder data */
925  IMD_data.left = This->frame->ImageDesc.Left;
926  IMD_data.top = This->frame->ImageDesc.Top;
927  IMD_data.width = This->frame->ImageDesc.Width;
928  IMD_data.height = This->frame->ImageDesc.Height;
929  IMD_data.packed = 0;
930  /* interlace_flag */
931  IMD_data.packed |= This->frame->ImageDesc.Interlace ? (1 << 6) : 0;
932  if (This->frame->ImageDesc.ColorMap)
933  {
934  /* local_color_table_flag */
935  IMD_data.packed |= 1 << 7;
936  /* local_color_table_size */
937  IMD_data.packed |= This->frame->ImageDesc.ColorMap->BitsPerPixel - 1;
938  /* sort_flag */
939  IMD_data.packed |= This->frame->ImageDesc.ColorMap->SortFlag ? 0x20 : 0;
940  }
941 
942  stream = create_stream(&IMD_data, sizeof(IMD_data));
943  IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionDefault);
944  IStream_Release(stream);
945 
946  IWICPersistStream_Release(persist);
947 
948  *reader = metadata_reader;
949  return S_OK;
950 }
951 
954 {
956  int i, gce_index = -1, gce_skipped = 0;
957 
958  TRACE("(%p,%u,%p)\n", iface, index, reader);
959 
960  if (!reader) return E_INVALIDARG;
961 
962  if (index == 0)
964 
965  if (index >= This->frame->Extensions.ExtensionBlockCount + 1)
966  return E_INVALIDARG;
967 
968  for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++)
969  {
970  class_constructor constructor;
971  const void *data;
972  int data_size;
973 
974  if (index != i + 1 - gce_skipped) continue;
975 
976  if (This->frame->Extensions.ExtensionBlocks[i].Function == GRAPHICS_EXT_FUNC_CODE)
977  {
978  gce_index = i;
979  gce_skipped = 1;
980  continue;
981  }
982  else if (This->frame->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE)
983  {
984  constructor = GifCommentReader_CreateInstance;
985  data = This->frame->Extensions.ExtensionBlocks[i].Bytes;
986  data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount;
987  }
988  else
989  {
991  data = This->frame->Extensions.ExtensionBlocks[i].Bytes;
992  data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount;
993  }
994  return create_metadata_reader(data, data_size, constructor, reader);
995  }
996 
997  if (gce_index == -1) return E_INVALIDARG;
998 
999  return create_metadata_reader(This->frame->Extensions.ExtensionBlocks[gce_index].Bytes + 3,
1000  This->frame->Extensions.ExtensionBlocks[gce_index].ByteCount - 4,
1002 }
1003 
1005  IEnumUnknown **enumerator)
1006 {
1007  FIXME("(%p,%p): stub\n", iface, enumerator);
1008  return E_NOTIMPL;
1009 }
1010 
1011 static const IWICMetadataBlockReaderVtbl GifFrameDecode_BlockVtbl =
1012 {
1020 };
1021 
1023  void **ppv)
1024 {
1026  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1027 
1028  if (!ppv) return E_INVALIDARG;
1029 
1030  if (IsEqualIID(&IID_IUnknown, iid) ||
1031  IsEqualIID(&IID_IWICBitmapDecoder, iid))
1032  {
1033  *ppv = &This->IWICBitmapDecoder_iface;
1034  }
1035  else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
1036  {
1037  *ppv = &This->IWICMetadataBlockReader_iface;
1038  }
1039  else
1040  {
1041  *ppv = NULL;
1042  return E_NOINTERFACE;
1043  }
1044 
1045  IUnknown_AddRef((IUnknown*)*ppv);
1046  return S_OK;
1047 }
1048 
1050 {
1053 
1054  TRACE("(%p) refcount=%u\n", iface, ref);
1055 
1056  return ref;
1057 }
1058 
1060 {
1063 
1064  TRACE("(%p) refcount=%u\n", iface, ref);
1065 
1066  if (ref == 0)
1067  {
1068  if (This->stream)
1069  {
1070  IStream_Release(This->stream);
1071  DGifCloseFile(This->gif);
1072  }
1073  This->lock.DebugInfo->Spare[0] = 0;
1074  DeleteCriticalSection(&This->lock);
1075  HeapFree(GetProcessHeap(), 0, This);
1076  }
1077 
1078  return ref;
1079 }
1080 
1082  DWORD *capability)
1083 {
1084  HRESULT hr;
1085 
1086  TRACE("(%p,%p,%p)\n", iface, stream, capability);
1087 
1088  if (!stream || !capability) return E_INVALIDARG;
1089 
1090  hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
1091  if (hr != S_OK) return hr;
1092 
1096  return S_OK;
1097 }
1098 
1099 static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
1100  IStream *stream = gif->UserData;
1101  ULONG bytesread;
1102  HRESULT hr;
1103 
1104  if (!stream)
1105  {
1106  ERR("attempting to read file after initialization\n");
1107  return 0;
1108  }
1109 
1110  hr = IStream_Read(stream, data, len, &bytesread);
1111  if (FAILED(hr)) bytesread = 0;
1112  return bytesread;
1113 }
1114 
1116  WICDecodeOptions cacheOptions)
1117 {
1120  int ret;
1121 
1122  TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
1123 
1124  EnterCriticalSection(&This->lock);
1125 
1126  if (This->initialized || This->gif)
1127  {
1128  WARN("already initialized\n");
1129  LeaveCriticalSection(&This->lock);
1130  return WINCODEC_ERR_WRONGSTATE;
1131  }
1132 
1133  /* seek to start of stream */
1134  seek.QuadPart = 0;
1135  IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
1136 
1137  /* read all data from the stream */
1138  This->gif = DGifOpen((void*)pIStream, _gif_inputfunc);
1139  if (!This->gif)
1140  {
1141  LeaveCriticalSection(&This->lock);
1142  return E_FAIL;
1143  }
1144 
1145  ret = DGifSlurp(This->gif);
1146  if (ret == GIF_ERROR)
1147  {
1148  LeaveCriticalSection(&This->lock);
1149  return E_FAIL;
1150  }
1151 
1152  /* make sure we don't use the stream after this method returns */
1153  This->gif->UserData = NULL;
1154 
1155  seek.QuadPart = 0;
1156  IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
1157  IStream_Read(pIStream, This->LSD_data, sizeof(This->LSD_data), NULL);
1158 
1159  This->stream = pIStream;
1160  IStream_AddRef(This->stream);
1161 
1162  This->initialized = TRUE;
1163 
1164  LeaveCriticalSection(&This->lock);
1165 
1166  return S_OK;
1167 }
1168 
1170  GUID *pguidContainerFormat)
1171 {
1172  memcpy(pguidContainerFormat, &GUID_ContainerFormatGif, sizeof(GUID));
1173  return S_OK;
1174 }
1175 
1177  IWICBitmapDecoderInfo **ppIDecoderInfo)
1178 {
1179  TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
1180 
1181  return get_decoder_info(&CLSID_WICGifDecoder, ppIDecoderInfo);
1182 }
1183 
1185 {
1187  WICColor colors[256];
1188  ColorMapObject *cm;
1189  int i, trans, count;
1190  ExtensionBlock *eb;
1191 
1192  TRACE("(%p,%p)\n", iface, palette);
1193 
1194  if (!This->gif)
1195  return WINCODEC_ERR_WRONGSTATE;
1196 
1197  cm = This->gif->SColorMap;
1198  if (cm)
1199  {
1200  if (cm->ColorCount > 256)
1201  {
1202  ERR("GIF contains invalid number of colors: %d\n", cm->ColorCount);
1203  return E_FAIL;
1204  }
1205 
1206  for (i = 0; i < cm->ColorCount; i++)
1207  {
1208  colors[i] = 0xff000000 | /* alpha */
1209  cm->Colors[i].Red << 16 |
1210  cm->Colors[i].Green << 8 |
1211  cm->Colors[i].Blue;
1212  }
1213 
1214  count = cm->ColorCount;
1215  }
1216  else
1217  {
1218  colors[0] = 0xff000000;
1219  colors[1] = 0xffffffff;
1220 
1221  for (i = 2; i < 256; i++)
1222  colors[i] = 0xff000000;
1223 
1224  count = 256;
1225  }
1226 
1227  /* look for the transparent color extension */
1228  for (i = 0; i < This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlockCount; i++)
1229  {
1230  eb = This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlocks + i;
1231  if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8)
1232  {
1233  if (eb->Bytes[3] & 1)
1234  {
1235  trans = (unsigned char)eb->Bytes[6];
1236  colors[trans] &= 0xffffff; /* set alpha to 0 */
1237  break;
1238  }
1239  }
1240  }
1241 
1242  return IWICPalette_InitializeCustom(palette, colors, count);
1243 }
1244 
1246  IWICMetadataQueryReader **ppIMetadataQueryReader)
1247 {
1249 
1250  TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
1251 
1252  if (!ppIMetadataQueryReader) return E_INVALIDARG;
1253 
1254  return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader);
1255 }
1256 
1258  IWICBitmapSource **ppIBitmapSource)
1259 {
1260  TRACE("(%p,%p)\n", iface, ppIBitmapSource);
1262 }
1263 
1265  UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
1266 {
1267  TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
1269 }
1270 
1272  IWICBitmapSource **ppIThumbnail)
1273 {
1274  TRACE("(%p,%p)\n", iface, ppIThumbnail);
1276 }
1277 
1279  UINT *pCount)
1280 {
1282 
1283  if (!pCount) return E_INVALIDARG;
1284 
1285  EnterCriticalSection(&This->lock);
1286  *pCount = This->gif ? This->gif->ImageCount : 0;
1287  LeaveCriticalSection(&This->lock);
1288 
1289  TRACE("(%p) <-- %d\n", iface, *pCount);
1290 
1291  return S_OK;
1292 }
1293 
1295  UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
1296 {
1299  TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
1300 
1301  if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING;
1302 
1303  if (index >= This->gif->ImageCount) return E_INVALIDARG;
1304 
1305  result = HeapAlloc(GetProcessHeap(), 0, sizeof(GifFrameDecode));
1306  if (!result) return E_OUTOFMEMORY;
1307 
1308  result->IWICBitmapFrameDecode_iface.lpVtbl = &GifFrameDecode_Vtbl;
1309  result->IWICMetadataBlockReader_iface.lpVtbl = &GifFrameDecode_BlockVtbl;
1310  result->ref = 1;
1311  result->frame = &This->gif->SavedImages[index];
1312  IWICBitmapDecoder_AddRef(iface);
1313  result->parent = This;
1314  This->current_frame = index;
1315 
1316  *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface;
1317 
1318  return S_OK;
1319 }
1320 
1321 static const IWICBitmapDecoderVtbl GifDecoder_Vtbl = {
1336 };
1337 
1339  REFIID iid, void **ppv)
1340 {
1342  return IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
1343 }
1344 
1346 {
1348  return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
1349 }
1350 
1352 {
1354  return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
1355 }
1356 
1358  GUID *guid)
1359 {
1360  TRACE("(%p,%p)\n", iface, guid);
1361 
1362  if (!guid) return E_INVALIDARG;
1363 
1364  *guid = GUID_ContainerFormatGif;
1365  return S_OK;
1366 }
1367 
1369  UINT *count)
1370 {
1372 
1373  TRACE("%p,%p\n", iface, count);
1374 
1375  if (!count) return E_INVALIDARG;
1376 
1377  *count = This->gif->Extensions.ExtensionBlockCount + 1;
1378  return S_OK;
1379 }
1380 
1383 {
1385  int i;
1386 
1387  TRACE("(%p,%u,%p)\n", iface, index, reader);
1388 
1389  if (!reader) return E_INVALIDARG;
1390 
1391  if (index == 0)
1392  return create_metadata_reader(This->LSD_data, sizeof(This->LSD_data),
1394 
1395  for (i = 0; i < This->gif->Extensions.ExtensionBlockCount; i++)
1396  {
1397  class_constructor constructor;
1398 
1399  if (index != i + 1) continue;
1400 
1401  if (This->gif->Extensions.ExtensionBlocks[i].Function == APPLICATION_EXT_FUNC_CODE)
1402  constructor = APEReader_CreateInstance;
1403  else if (This->gif->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE)
1404  constructor = GifCommentReader_CreateInstance;
1405  else
1407 
1408  return create_metadata_reader(This->gif->Extensions.ExtensionBlocks[i].Bytes,
1409  This->gif->Extensions.ExtensionBlocks[i].ByteCount,
1410  constructor, reader);
1411  }
1412 
1413  return E_INVALIDARG;
1414 }
1415 
1417  IEnumUnknown **enumerator)
1418 {
1419  FIXME("(%p,%p): stub\n", iface, enumerator);
1420  return E_NOTIMPL;
1421 }
1422 
1423 static const IWICMetadataBlockReaderVtbl GifDecoder_BlockVtbl =
1424 {
1432 };
1433 
1435 {
1436  GifDecoder *This;
1437  HRESULT ret;
1438 
1439  TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
1440 
1441  *ppv = NULL;
1442 
1443  This = HeapAlloc(GetProcessHeap(), 0, sizeof(GifDecoder));
1444  if (!This) return E_OUTOFMEMORY;
1445 
1446  This->IWICBitmapDecoder_iface.lpVtbl = &GifDecoder_Vtbl;
1447  This->IWICMetadataBlockReader_iface.lpVtbl = &GifDecoder_BlockVtbl;
1448  This->stream = NULL;
1449  This->ref = 1;
1450  This->initialized = FALSE;
1451  This->gif = NULL;
1452  This->current_frame = 0;
1454  This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock");
1455 
1456  ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
1457  IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
1458 
1459  return ret;
1460 }
1461 
1462 typedef struct GifEncoder
1463 {
1472 } GifEncoder;
1473 
1475 {
1476  return CONTAINING_RECORD(iface, GifEncoder, IWICBitmapEncoder_iface);
1477 }
1478 
1479 typedef struct GifFrameEncode
1480 {
1486  double xres, yres;
1490 } GifFrameEncode;
1491 
1493 {
1494  return CONTAINING_RECORD(iface, GifFrameEncode, IWICBitmapFrameEncode_iface);
1495 }
1496 
1498 {
1499  TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv);
1500 
1501  if (!ppv) return E_INVALIDARG;
1502 
1503  if (IsEqualIID(&IID_IUnknown, iid) ||
1504  IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
1505  {
1506  IWICBitmapFrameEncode_AddRef(iface);
1507  *ppv = iface;
1508  return S_OK;
1509  }
1510 
1511  *ppv = NULL;
1512  return E_NOINTERFACE;
1513 }
1514 
1516 {
1519 
1520  TRACE("%p -> %u\n", iface, ref);
1521  return ref;
1522 }
1523 
1525 {
1528 
1529  TRACE("%p -> %u\n", iface, ref);
1530 
1531  if (!ref)
1532  {
1533  IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface);
1534  HeapFree(GetProcessHeap(), 0, This->image_data);
1535  HeapFree(GetProcessHeap(), 0, This);
1536  }
1537 
1538  return ref;
1539 }
1540 
1542 {
1544  HRESULT hr;
1545 
1546  TRACE("%p,%p\n", iface, options);
1547 
1548  EnterCriticalSection(&This->encoder->lock);
1549 
1550  if (!This->initialized)
1551  {
1552  This->initialized = TRUE;
1553  hr = S_OK;
1554  }
1555  else
1557 
1558  LeaveCriticalSection(&This->encoder->lock);
1559 
1560  return hr;
1561 }
1562 
1564 {
1566  HRESULT hr;
1567 
1568  TRACE("%p,%u,%u\n", iface, width, height);
1569 
1570  if (!width || !height) return E_INVALIDARG;
1571 
1572  EnterCriticalSection(&This->encoder->lock);
1573 
1574  if (This->initialized)
1575  {
1576  HeapFree(GetProcessHeap(), 0, This->image_data);
1577 
1578  This->image_data = HeapAlloc(GetProcessHeap(), 0, width * height);
1579  if (This->image_data)
1580  {
1581  This->width = width;
1582  This->height = height;
1583  hr = S_OK;
1584  }
1585  else
1586  hr = E_OUTOFMEMORY;
1587  }
1588  else
1590 
1591  LeaveCriticalSection(&This->encoder->lock);
1592 
1593  return hr;
1594 }
1595 
1596 static HRESULT WINAPI GifFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double xres, double yres)
1597 {
1599  HRESULT hr;
1600 
1601  TRACE("%p,%f,%f\n", iface, xres, yres);
1602 
1603  EnterCriticalSection(&This->encoder->lock);
1604 
1605  if (This->initialized)
1606  {
1607  This->xres = xres;
1608  This->yres = yres;
1609  hr = S_OK;
1610  }
1611  else
1613 
1614  LeaveCriticalSection(&This->encoder->lock);
1615 
1616  return hr;
1617 }
1618 
1620 {
1622  HRESULT hr;
1623 
1624  TRACE("%p,%s\n", iface, debugstr_guid(format));
1625 
1626  if (!format) return E_INVALIDARG;
1627 
1628  EnterCriticalSection(&This->encoder->lock);
1629 
1630  if (This->initialized)
1631  {
1632  *format = GUID_WICPixelFormat8bppIndexed;
1633  hr = S_OK;
1634  }
1635  else
1637 
1638  LeaveCriticalSection(&This->encoder->lock);
1639 
1640  return hr;
1641 }
1642 
1644 {
1645  FIXME("%p,%u,%p: stub\n", iface, count, context);
1646  return E_NOTIMPL;
1647 }
1648 
1650 {
1652  HRESULT hr;
1653 
1654  TRACE("%p,%p\n", iface, palette);
1655 
1656  if (!palette) return E_INVALIDARG;
1657 
1658  EnterCriticalSection(&This->encoder->lock);
1659 
1660  if (This->initialized)
1661  hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
1662  else
1664 
1665  LeaveCriticalSection(&This->encoder->lock);
1666  return hr;
1667 }
1668 
1670 {
1671  FIXME("%p,%p: stub\n", iface, thumbnail);
1672  return E_NOTIMPL;
1673 }
1674 
1676 {
1678  HRESULT hr;
1679 
1680  TRACE("%p,%u,%u,%u,%p\n", iface, lines, stride, size, pixels);
1681 
1682  if (!pixels) return E_INVALIDARG;
1683 
1684  EnterCriticalSection(&This->encoder->lock);
1685 
1686  if (This->initialized && This->image_data)
1687  {
1688  if (This->lines + lines <= This->height)
1689  {
1690  UINT i;
1691  BYTE *src, *dst;
1692 
1693  src = pixels;
1694  dst = This->image_data + This->lines * This->width;
1695 
1696  for (i = 0; i < lines; i++)
1697  {
1698  memcpy(dst, src, This->width);
1699  src += stride;
1700  dst += This->width;
1701  }
1702 
1703  This->lines += lines;
1704  hr = S_OK;
1705  }
1706  else
1707  hr = E_INVALIDARG;
1708  }
1709  else
1711 
1712  LeaveCriticalSection(&This->encoder->lock);
1713  return hr;
1714 }
1715 
1717 {
1719  HRESULT hr;
1720 
1721  TRACE("%p,%p,%p\n", iface, source, rc);
1722 
1723  if (!source) return E_INVALIDARG;
1724 
1725  EnterCriticalSection(&This->encoder->lock);
1726 
1727  if (This->initialized)
1728  {
1729  const GUID *format = &GUID_WICPixelFormat8bppIndexed;
1730 
1731  hr = configure_write_source(iface, source, rc, format,
1732  This->width, This->height, This->xres, This->yres);
1733  if (hr == S_OK)
1734  hr = write_source(iface, source, rc, format, 8, This->width, This->height);
1735  }
1736  else
1738 
1739  LeaveCriticalSection(&This->encoder->lock);
1740  return hr;
1741 }
1742 
1743 #define LZW_DICT_SIZE (1 << 12)
1744 
1745 struct lzw_dict
1746 {
1748  unsigned char suffix[LZW_DICT_SIZE];
1749 };
1750 
1752 {
1753  struct lzw_dict dict;
1755  unsigned bits_buf;
1757  int (*user_write_data)(void *user_ptr, void *data, int length);
1758  void *user_ptr;
1759 };
1760 
1762 {
1763  unsigned len;
1764  const BYTE *in;
1765 };
1766 
1768 {
1769  struct
1770  {
1771  unsigned char len;
1772  char data[255];
1773  } gif_block;
1775 };
1776 
1777 static int lzw_output_code(struct lzw_state *state, short code)
1778 {
1779  state->bits_buf |= code << state->bits_count;
1780  state->bits_count += state->code_bits;
1781 
1782  while (state->bits_count >= 8)
1783  {
1784  unsigned char byte = (unsigned char)state->bits_buf;
1785  if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
1786  return 0;
1787  state->bits_buf >>= 8;
1788  state->bits_count -= 8;
1789  }
1790 
1791  return 1;
1792 }
1793 
1794 static inline int lzw_output_clear_code(struct lzw_state *state)
1795 {
1796  return lzw_output_code(state, state->clear_code);
1797 }
1798 
1799 static inline int lzw_output_eof_code(struct lzw_state *state)
1800 {
1801  return lzw_output_code(state, state->eof_code);
1802 }
1803 
1804 static int lzw_flush_bits(struct lzw_state *state)
1805 {
1806  unsigned char byte;
1807 
1808  while (state->bits_count >= 8)
1809  {
1810  byte = (unsigned char)state->bits_buf;
1811  if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
1812  return 0;
1813  state->bits_buf >>= 8;
1814  state->bits_count -= 8;
1815  }
1816 
1817  if (state->bits_count)
1818  {
1819  static const char mask[8] = { 0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f };
1820 
1821  byte = (unsigned char)state->bits_buf & mask[state->bits_count];
1822  if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
1823  return 0;
1824  }
1825 
1826  state->bits_buf = 0;
1827  state->bits_count = 0;
1828 
1829  return 1;
1830 }
1831 
1832 static void lzw_dict_reset(struct lzw_state *state)
1833 {
1834  int i;
1835 
1836  state->code_bits = state->init_code_bits + 1;
1837  state->next_code = (1 << state->init_code_bits) + 2;
1838 
1839  for(i = 0; i < LZW_DICT_SIZE; i++)
1840  {
1841  state->dict.prefix[i] = 1 << 12; /* impossible LZW code value */
1842  state->dict.suffix[i] = 0;
1843  }
1844 }
1845 
1846 static void lzw_state_init(struct lzw_state *state, short init_code_bits, void *user_write_data, void *user_ptr)
1847 {
1848  state->init_code_bits = init_code_bits;
1849  state->clear_code = 1 << init_code_bits;
1850  state->eof_code = state->clear_code + 1;
1851  state->bits_buf = 0;
1852  state->bits_count = 0;
1853  state->user_write_data = user_write_data;
1854  state->user_ptr = user_ptr;
1855 
1857 }
1858 
1859 static int lzw_dict_add(struct lzw_state *state, short prefix, unsigned char suffix)
1860 {
1861  if (state->next_code < LZW_DICT_SIZE)
1862  {
1863  state->dict.prefix[state->next_code] = prefix;
1864  state->dict.suffix[state->next_code] = suffix;
1865 
1866  if ((state->next_code & (state->next_code - 1)) == 0)
1867  state->code_bits++;
1868 
1869  state->next_code++;
1870  return state->next_code;
1871  }
1872 
1873  return -1;
1874 }
1875 
1876 static short lzw_dict_lookup(const struct lzw_state *state, short prefix, unsigned char suffix)
1877 {
1878  short i;
1879 
1880  for (i = 0; i < state->next_code; i++)
1881  {
1882  if (state->dict.prefix[i] == prefix && state->dict.suffix[i] == suffix)
1883  return i;
1884  }
1885 
1886  return -1;
1887 }
1888 
1889 static inline int write_byte(struct output_stream *out, char byte)
1890 {
1891  if (out->gif_block.len == 255)
1892  {
1893  if (IStream_Write(out->out, &out->gif_block, sizeof(out->gif_block), NULL) != S_OK)
1894  return 0;
1895 
1896  out->gif_block.len = 0;
1897  }
1898 
1899  out->gif_block.data[out->gif_block.len++] = byte;
1900 
1901  return 1;
1902 }
1903 
1904 static int write_data(void *user_ptr, void *user_data, int length)
1905 {
1906  unsigned char *data = user_data;
1907  struct output_stream *out = user_ptr;
1908  int len = length;
1909 
1910  while (len-- > 0)
1911  {
1912  if (!write_byte(out, *data++)) return 0;
1913  }
1914 
1915  return length;
1916 }
1917 
1918 static int flush_output_data(void *user_ptr)
1919 {
1920  struct output_stream *out = user_ptr;
1921 
1922  if (out->gif_block.len)
1923  {
1924  if (IStream_Write(out->out, &out->gif_block, out->gif_block.len + sizeof(out->gif_block.len), NULL) != S_OK)
1925  return 0;
1926  }
1927 
1928  /* write GIF block terminator */
1929  out->gif_block.len = 0;
1930  return IStream_Write(out->out, &out->gif_block, sizeof(out->gif_block.len), NULL) == S_OK;
1931 }
1932 
1933 static inline int read_byte(struct input_stream *in, unsigned char *byte)
1934 {
1935  if (in->len)
1936  {
1937  in->len--;
1938  *byte = *in->in++;
1939  return 1;
1940  }
1941 
1942  return 0;
1943 }
1944 
1945 static HRESULT gif_compress(IStream *out_stream, const BYTE *in_data, ULONG in_size)
1946 {
1947  struct input_stream in;
1948  struct output_stream out;
1949  struct lzw_state state;
1950  short init_code_bits, prefix, code;
1951  unsigned char suffix;
1952 
1953  in.in = in_data;
1954  in.len = in_size;
1955 
1956  out.gif_block.len = 0;
1957  out.out = out_stream;
1958 
1959  init_code_bits = suffix = 8;
1960  if (IStream_Write(out.out, &suffix, sizeof(suffix), NULL) != S_OK)
1961  return E_FAIL;
1962 
1964 
1966  return E_FAIL;
1967 
1968  if (read_byte(&in, &suffix))
1969  {
1970  prefix = suffix;
1971 
1972  while (read_byte(&in, &suffix))
1973  {
1974  code = lzw_dict_lookup(&state, prefix, suffix);
1975  if (code == -1)
1976  {
1977  if (!lzw_output_code(&state, prefix))
1978  return E_FAIL;
1979 
1980  if (lzw_dict_add(&state, prefix, suffix) == -1)
1981  {
1983  return E_FAIL;
1985  }
1986 
1987  prefix = suffix;
1988  }
1989  else
1990  prefix = code;
1991  }
1992 
1993  if (!lzw_output_code(&state, prefix))
1994  return E_FAIL;
1995  if (!lzw_output_eof_code(&state))
1996  return E_FAIL;
1997  if (!lzw_flush_bits(&state))
1998  return E_FAIL;
1999  }
2000 
2001  return flush_output_data(&out) ? S_OK : E_FAIL;
2002 }
2003 
2005 {
2007  HRESULT hr;
2008 
2009  TRACE("%p\n", iface);
2010 
2011  EnterCriticalSection(&This->encoder->lock);
2012 
2013  if (This->image_data && This->lines == This->height && !This->committed)
2014  {
2015  BYTE gif_palette[256][3];
2016 
2017  hr = S_OK;
2018 
2019  if (!This->encoder->info_written)
2020  {
2021  struct logical_screen_descriptor lsd;
2022 
2023  /* Logical Screen Descriptor */
2024  memcpy(lsd.signature, "GIF89a", 6);
2025  lsd.width = This->width;
2026  lsd.height = This->height;
2027  lsd.packed = 0;
2028  if (This->encoder->colors)
2029  lsd.packed |= 0x80; /* global color table flag */
2030  lsd.packed |= 0x07 << 4; /* color resolution */
2031  lsd.packed |= 0x07; /* global color table size */
2032  lsd.background_color_index = 0; /* FIXME */
2033  lsd.pixel_aspect_ratio = 0;
2034  hr = IStream_Write(This->encoder->stream, &lsd, sizeof(lsd), NULL);
2035  if (hr == S_OK && This->encoder->colors)
2036  {
2037  UINT i;
2038 
2039  /* Global Color Table */
2040  memset(gif_palette, 0, sizeof(gif_palette));
2041  for (i = 0; i < This->encoder->colors; i++)
2042  {
2043  gif_palette[i][0] = (This->encoder->palette[i] >> 16) & 0xff;
2044  gif_palette[i][1] = (This->encoder->palette[i] >> 8) & 0xff;
2045  gif_palette[i][2] = This->encoder->palette[i] & 0xff;
2046  }
2047  hr = IStream_Write(This->encoder->stream, gif_palette, sizeof(gif_palette), NULL);
2048  }
2049 
2050  /* FIXME: write GCE, APE, etc. GIF extensions */
2051 
2052  if (hr == S_OK)
2053  This->encoder->info_written = TRUE;
2054  }
2055 
2056  if (hr == S_OK)
2057  {
2058  char image_separator = 0x2c;
2059 
2060  hr = IStream_Write(This->encoder->stream, &image_separator, sizeof(image_separator), NULL);
2061  if (hr == S_OK)
2062  {
2063  struct image_descriptor imd;
2064 
2065  /* Image Descriptor */
2066  imd.left = 0;
2067  imd.top = 0;
2068  imd.width = This->width;
2069  imd.height = This->height;
2070  imd.packed = 0;
2071  if (This->colors)
2072  {
2073  imd.packed |= 0x80; /* local color table flag */
2074  imd.packed |= 0x07; /* local color table size */
2075  }
2076  /* FIXME: interlace flag */
2077  hr = IStream_Write(This->encoder->stream, &imd, sizeof(imd), NULL);
2078  if (hr == S_OK && This->colors)
2079  {
2080  UINT i;
2081 
2082  /* Local Color Table */
2083  memset(gif_palette, 0, sizeof(gif_palette));
2084  for (i = 0; i < This->colors; i++)
2085  {
2086  gif_palette[i][0] = (This->palette[i] >> 16) & 0xff;
2087  gif_palette[i][1] = (This->palette[i] >> 8) & 0xff;
2088  gif_palette[i][2] = This->palette[i] & 0xff;
2089  }
2090  hr = IStream_Write(This->encoder->stream, gif_palette, sizeof(gif_palette), NULL);
2091  if (hr == S_OK)
2092  {
2093  /* Image Data */
2094  hr = gif_compress(This->encoder->stream, This->image_data, This->width * This->height);
2095  if (hr == S_OK)
2096  This->committed = TRUE;
2097  }
2098  }
2099  }
2100  }
2101  }
2102  else
2104 
2105  LeaveCriticalSection(&This->encoder->lock);
2106  return hr;
2107 }
2108 
2110 {
2111  FIXME("%p, %p: stub\n", iface, writer);
2112  return E_NOTIMPL;
2113 }
2114 
2115 static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl =
2116 {
2131 };
2132 
2134 {
2135  TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv);
2136 
2137  if (!ppv) return E_INVALIDARG;
2138 
2139  if (IsEqualIID(&IID_IUnknown, iid) ||
2140  IsEqualIID(&IID_IWICBitmapEncoder, iid))
2141  {
2142  IWICBitmapEncoder_AddRef(iface);
2143  *ppv = iface;
2144  return S_OK;
2145  }
2146 
2147  *ppv = NULL;
2148  return E_NOINTERFACE;
2149 }
2150 
2152 {
2155 
2156  TRACE("%p -> %u\n", iface, ref);
2157  return ref;
2158 }
2159 
2161 {
2164 
2165  TRACE("%p -> %u\n", iface, ref);
2166 
2167  if (!ref)
2168  {
2169  if (This->stream) IStream_Release(This->stream);
2170  This->lock.DebugInfo->Spare[0] = 0;
2171  DeleteCriticalSection(&This->lock);
2172  HeapFree(GetProcessHeap(), 0, This);
2173  }
2174 
2175  return ref;
2176 }
2177 
2179 {
2181  HRESULT hr;
2182 
2183  TRACE("%p,%p,%#x\n", iface, stream, option);
2184 
2185  if (!stream) return E_INVALIDARG;
2186 
2187  EnterCriticalSection(&This->lock);
2188 
2189  if (!This->initialized)
2190  {
2191  IStream_AddRef(stream);
2192  This->stream = stream;
2193  This->initialized = TRUE;
2194  hr = S_OK;
2195  }
2196  else
2198 
2199  LeaveCriticalSection(&This->lock);
2200 
2201  return hr;
2202 }
2203 
2205 {
2206  if (!format) return E_INVALIDARG;
2207 
2208  *format = GUID_ContainerFormatGif;
2209  return S_OK;
2210 }
2211 
2213 {
2214  IWICComponentInfo *comp_info;
2215  HRESULT hr;
2216 
2217  TRACE("%p,%p\n", iface, info);
2218 
2219  if (!info) return E_INVALIDARG;
2220 
2221  hr = CreateComponentInfo(&CLSID_WICGifEncoder, &comp_info);
2222  if (hr == S_OK)
2223  {
2224  hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
2225  IWICComponentInfo_Release(comp_info);
2226  }
2227  return hr;
2228 }
2229 
2231 {
2232  FIXME("%p,%u,%p: stub\n", iface, count, context);
2233  return E_NOTIMPL;
2234 }
2235 
2237 {
2239  HRESULT hr;
2240 
2241  TRACE("%p,%p\n", iface, palette);
2242 
2243  if (!palette) return E_INVALIDARG;
2244 
2245  EnterCriticalSection(&This->lock);
2246 
2247  if (This->initialized)
2248  hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
2249  else
2251 
2252  LeaveCriticalSection(&This->lock);
2253  return hr;
2254 }
2255 
2257 {
2258  TRACE("%p,%p\n", iface, thumbnail);
2260 }
2261 
2263 {
2264  TRACE("%p,%p\n", iface, preview);
2266 }
2267 
2269 {
2271  HRESULT hr;
2272 
2273  TRACE("%p,%p,%p\n", iface, frame, options);
2274 
2275  if (!frame) return E_INVALIDARG;
2276 
2277  EnterCriticalSection(&This->lock);
2278 
2279  if (This->initialized && !This->committed)
2280  {
2281  GifFrameEncode *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
2282  if (ret)
2283  {
2284  This->n_frames++;
2285 
2286  ret->IWICBitmapFrameEncode_iface.lpVtbl = &GifFrameEncode_Vtbl;
2287  ret->ref = 1;
2288  ret->encoder = This;
2289  ret->initialized = FALSE;
2290  ret->interlace = FALSE; /* FIXME: read from the properties */
2291  ret->committed = FALSE;
2292  ret->width = 0;
2293  ret->height = 0;
2294  ret->lines = 0;
2295  ret->xres = 0.0;
2296  ret->yres = 0.0;
2297  ret->colors = 0;
2298  ret->image_data = NULL;
2299  IWICBitmapEncoder_AddRef(iface);
2300  *frame = &ret->IWICBitmapFrameEncode_iface;
2301 
2302  hr = S_OK;
2303 
2304  if (options)
2305  {
2307  if (hr != S_OK)
2308  {
2309  IWICBitmapFrameEncode_Release(*frame);
2310  *frame = NULL;
2311  }
2312  }
2313  }
2314  else
2315  hr = E_OUTOFMEMORY;
2316  }
2317  else
2319 
2320  LeaveCriticalSection(&This->lock);
2321 
2322  return hr;
2323 
2324 }
2325 
2327 {
2329  HRESULT hr;
2330 
2331  TRACE("%p\n", iface);
2332 
2333  EnterCriticalSection(&This->lock);
2334 
2335  if (This->initialized && !This->committed)
2336  {
2337  char gif_trailer = 0x3b;
2338 
2339  /* FIXME: write text, comment GIF extensions */
2340 
2341  hr = IStream_Write(This->stream, &gif_trailer, sizeof(gif_trailer), NULL);
2342  if (hr == S_OK)
2343  This->committed = TRUE;
2344  }
2345  else
2347 
2348  LeaveCriticalSection(&This->lock);
2349  return hr;
2350 }
2351 
2353 {
2354  FIXME("%p,%p: stub\n", iface, writer);
2355  return E_NOTIMPL;
2356 }
2357 
2358 static const IWICBitmapEncoderVtbl GifEncoder_Vtbl =
2359 {
2373 };
2374 
2376 {
2377  GifEncoder *This;
2378  HRESULT ret;
2379 
2380  TRACE("%s,%p\n", debugstr_guid(iid), ppv);
2381 
2382  *ppv = NULL;
2383 
2384  This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2385  if (!This) return E_OUTOFMEMORY;
2386 
2387  This->IWICBitmapEncoder_iface.lpVtbl = &GifEncoder_Vtbl;
2388  This->ref = 1;
2389  This->stream = NULL;
2391  This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifEncoder.lock");
2392  This->initialized = FALSE;
2393  This->info_written = FALSE;
2394  This->committed = FALSE;
2395  This->n_frames = 0;
2396  This->colors = 0;
2397 
2398  ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
2399  IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
2400 
2401  return ret;
2402 }
static GifFrameDecode * impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:612
union value::@484 u
#define GIF_ERROR
Definition: ungif.h:55
unsigned char len
Definition: gifformat.c:1771
static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:332
HRESULT GifDecoder_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:1434
IWICMetadataBlockReader IWICMetadataBlockReader_iface
Definition: gifformat.c:584
GLint GLint GLsizei width
Definition: gl.h:1546
UINT current_frame
Definition: gifformat.c:590
static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1524
static int read_byte(struct input_stream *in, unsigned char *byte)
Definition: gifformat.c:1933
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:249
WICColor palette[256]
Definition: gifformat.c:1487
#define DWORD_PTR
Definition: treelist.c:76
HRESULT hr
Definition: shlfolder.c:183
HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void **ppv)
static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, IWICMetadataQueryWriter **writer)
Definition: gifformat.c:2109
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
static LPWSTR strdupAtoW(const char *src)
Definition: gifformat.c:77
SavedImage * frame
Definition: gifformat.c:598
Definition: http.c:6587
const BYTE * in
Definition: gifformat.c:1764
static HRESULT gif_compress(IStream *out_stream, const BYTE *in_data, ULONG in_size)
Definition: gifformat.c:1945
static HRESULT WINAPI GifDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, IWICBitmapDecoderInfo **ppIDecoderInfo)
Definition: gifformat.c:1176
CRITICAL_SECTION lock
Definition: gifformat.c:591
static HRESULT WINAPI GifFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *format)
Definition: gifformat.c:1619
static HRESULT WINAPI GifDecoder_GetColorContexts(IWICBitmapDecoder *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: gifformat.c:1264
static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1515
static HRESULT WINAPI GifDecoder_GetPreview(IWICBitmapDecoder *iface, IWICBitmapSource **ppIBitmapSource)
Definition: gifformat.c:1257
short eof_code
Definition: gifformat.c:1754
CRITICAL_SECTION lock
Definition: gifformat.c:1467
#define CP_ACP
Definition: compat.h:99
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define WARN(fmt,...)
Definition: debug.h:111
unsigned len
Definition: gifformat.c:1763
REFIID LPVOID * ppv
Definition: atlbase.h:39
static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl
Definition: gifformat.c:2115
static int lzw_dict_add(struct lzw_state *state, short prefix, unsigned char suffix)
Definition: gifformat.c:1859
static HRESULT WINAPI GifEncoder_Commit(IWICBitmapEncoder *iface)
Definition: gifformat.c:2326
static ULONG WINAPI GifFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface)
Definition: gifformat.c:868
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
#define WINCODEC_ERR_NOTINITIALIZED
Definition: winerror.h:3277
GifEncoder * encoder
Definition: gifformat.c:1483
short clear_code
Definition: gifformat.c:1754
static HRESULT WINAPI GifEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, IWICMetadataQueryWriter **writer)
Definition: gifformat.c:2352
static ULONG WINAPI GifDecoder_Block_Release(IWICMetadataBlockReader *iface)
Definition: gifformat.c:1351
static HRESULT WINAPI GifFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lines, UINT stride, UINT size, BYTE *pixels)
Definition: gifformat.c:1675
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **reader)
Definition: gifformat.c:952
WICBitmapEncoderCacheOption
Definition: wincodec.idl:69
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT WINAPI GifEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
Definition: gifformat.c:2212
static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv)
Definition: gifformat.c:622
static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **frame, IPropertyBag2 **options)
Definition: gifformat.c:2268
int32_t INT
Definition: typedefs.h:56
static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT width, UINT height)
Definition: gifformat.c:1563
HRESULT APEReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:434
Definition: send.c:47
struct GifEncoder GifEncoder
& rect
Definition: startmenu.cpp:1413
static HRESULT WINAPI GifDecoder_Block_GetCount(IWICMetadataBlockReader *iface, UINT *count)
Definition: gifformat.c:1368
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
IWICBitmapDecoder IWICBitmapDecoder_iface
Definition: gifformat.c:583
static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len)
Definition: gifformat.c:1099
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
int Function
Definition: ungif.h:103
static void lzw_dict_reset(struct lzw_state *state)
Definition: gifformat.c:1832
static HRESULT WINAPI GifDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: gifformat.c:1245
static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
Definition: gifformat.c:1294
short init_code_bits
Definition: gifformat.c:1754
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
HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:2375
const GUID * guid
WICColor palette[256]
Definition: gifformat.c:1470
int DGifCloseFile(GifFileType *GifFile)
Definition: ungif.c:1047
static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY)
Definition: gifformat.c:696
GLenum GLint GLuint mask
Definition: glext.h:6028
int ByteCount
Definition: ungif.h:104
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned char GifByteType
Definition: ungif.h:80
GifByteType Red
Definition: ungif.h:85
static const MetadataHandlerVtbl GifCommentReader_Vtbl
Definition: gifformat.c:522
static HRESULT WINAPI GifEncoder_SetColorContexts(IWICBitmapEncoder *iface, UINT count, IWICColorContext **context)
Definition: gifformat.c:2230
unsigned int BOOL
Definition: ntddk_ex.h:94
GifByteType Green
Definition: ungif.h:85
HRESULT write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, UINT bpp, INT width, INT height)
Definition: main.c:155
long LONG
Definition: pedump.c:60
static GifFrameDecode * frame_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
Definition: gifformat.c:617
#define COMMENT_EXT_FUNC_CODE
Definition: ungif.h:141
static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:439
BOOL info_written
Definition: gifformat.c:1468
void * user_ptr
Definition: gifformat.c:1758
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static HRESULT WINAPI GifFrameDecode_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight)
Definition: gifformat.c:676
static ULONG WINAPI GifFrameDecode_Block_Release(IWICMetadataBlockReader *iface)
Definition: gifformat.c:874
static HRESULT WINAPI GifDecoder_GetFrameCount(IWICBitmapDecoder *iface, UINT *pCount)
Definition: gifformat.c:1278
#define E_INVALIDARG
Definition: ddrawi.h:101
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
UINT colors
Definition: gifformat.c:1471
Definition: getopt.h:108
unsigned char
Definition: typeof.h:29
static int lzw_flush_bits(struct lzw_state *state)
Definition: gifformat.c:1804
static HRESULT WINAPI GifEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, void **ppv)
Definition: gifformat.c:2133
BOOL initialized
Definition: gifformat.c:588
short code_bits
Definition: gifformat.c:1754
static int flush_output_data(void *user_ptr)
Definition: gifformat.c:1918
static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, WICDecodeOptions cacheOptions)
Definition: gifformat.c:1115
HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:528
GLuint index
Definition: glext.h:6031
char * Bytes
Definition: ungif.h:105
INT Height
Definition: wincodec.idl:239
#define debugstr_guid
Definition: kernel32.h:35
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
UINT n_frames
Definition: gifformat.c:1469
BYTE * image_data
Definition: gifformat.c:1489
static GifDecoder * impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
Definition: gifformat.c:602
HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
Definition: info.c:2075
int bits_count
Definition: gifformat.c:1756
static HRESULT WINAPI GifDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *guid)
Definition: gifformat.c:1357
static const IWICBitmapDecoderVtbl GifDecoder_Vtbl
Definition: gifformat.c:1321
BOOL initialized
Definition: gifformat.c:1468
eMaj lines
Definition: tritemp.h:206
static HRESULT create_IMD_metadata_reader(GifFrameDecode *This, IWICMetadataReader **reader)
Definition: gifformat.c:904
static HRESULT WINAPI GifEncoder_Initialize(IWICBitmapEncoder *iface, IStream *stream, WICBitmapEncoderCacheOption option)
Definition: gifformat.c:2178
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface
Definition: gifformat.c:595
#define LZW_DICT_SIZE
Definition: gifformat.c:1743
#define TRACE(s)
Definition: solgame.cpp:4
static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl
Definition: gifformat.c:847
GLsizei stride
Definition: glext.h:5848
GLsizeiptr size
Definition: glext.h:5919
IWICBitmapFrameEncode IWICBitmapFrameEncode_iface
Definition: gifformat.c:1481
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
static HRESULT WINAPI GifFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette *palette)
Definition: gifformat.c:1649
__wchar_t WCHAR
Definition: xmlstorage.h:180
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static const WCHAR gif_extension[]
Definition: image.c:4739
static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:650
static int lzw_output_eof_code(struct lzw_state *state)
Definition: gifformat.c:1799
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct output_stream::@577 gif_block
const GUID IID_IUnknown
const WCHAR * vendor
Definition: db.cpp:863
void * UserData
Definition: ungif.h:124
static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette)
Definition: gifformat.c:710
int(* user_write_data)(void *user_ptr, void *data, int length)
Definition: gifformat.c:1757
IWICMetadataBlockReader IWICMetadataBlockReader_iface
Definition: gifformat.c:596
#define WINAPI
Definition: msvc.h:8
static HRESULT WINAPI GifDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, DWORD *capability)
Definition: gifformat.c:1081
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:100
static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: gifformat.c:833
static HRESULT WINAPI GifFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *guid)
Definition: gifformat.c:880
static const MetadataHandlerVtbl LSDReader_Vtbl
Definition: gifformat.c:162
static HRESULT create_metadata_reader(const void *data, int data_size, class_constructor constructor, IWICMetadataReader **reader)
Definition: gifformat.c:551
GifFileType * DGifOpen(void *userData, InputFunc readFunc)
Definition: ungif.c:993
#define WINCODEC_ERR_CODECNOTHUMBNAIL
Definition: winerror.h:3283
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:2004
static IStream * create_stream(const void *data, int data_size)
Definition: gifformat.c:533
IStream * out
Definition: gifformat.c:1774
IStream * stream
Definition: gifformat.c:1466
static HRESULT WINAPI GifFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, UINT count, IWICColorContext **context)
Definition: gifformat.c:1643
static HRESULT WINAPI GifFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double xres, double yres)
Definition: gifformat.c:1596
LONG ref
Definition: gifformat.c:587
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
int ret
#define WINCODEC_ERR_FRAMEMISSING
Definition: winerror.h:3293
int GifWord
Definition: ungif.h:82
static HRESULT WINAPI GifFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, void **ppv)
Definition: gifformat.c:861
#define index(s, c)
Definition: various.h:29
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
void delay(unsigned msec)
Definition: i386rtl.c:32
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, IEnumUnknown **enumerator)
Definition: gifformat.c:1004
static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface)
Definition: gifformat.c:2151
static HRESULT WINAPI GifFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat)
Definition: gifformat.c:688
GLuint GLuint stream
Definition: glext.h:7522
BOOL committed
Definition: gifformat.c:1468
static HRESULT WINAPI GifFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
Definition: gifformat.c:800
static HRESULT WINAPI GifFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *options)
Definition: gifformat.c:1541
static const char * debug_wic_rect(const WICRect *rect)
static int state
Definition: maze.c:121
#define APPLICATION_EXT_FUNC_CODE
Definition: ungif.h:144
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
static HRESULT WINAPI GifDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1338
unsigned char BYTE
Definition: mem.h:68
static HRESULT WINAPI GifEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *thumbnail)
Definition: gifformat.c:2256
unsigned bits_buf
Definition: gifformat.c:1755
GLenum src
Definition: glext.h:6340
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
Definition: winerror.h:3300
HRESULT(* class_constructor)(REFIID, void **)
GifDecoder * parent
Definition: gifformat.c:599
int code
Definition: i386-dis.c:3591
IWICBitmapEncoder IWICBitmapEncoder_iface
Definition: gifformat.c:1464
static HPALETTE palette
Definition: clipboard.c:1345
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
static HRESULT WINAPI GifDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **reader)
Definition: gifformat.c:1381
GifFileType * gif
Definition: gifformat.c:589
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
HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:168
static HRESULT WINAPI GifFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, IWICBitmapSource *thumbnail)
Definition: gifformat.c:1669
#define ERR(fmt,...)
Definition: debug.h:109
WICDecodeOptions
Definition: wincodec.idl:27
static void lzw_state_init(struct lzw_state *state, short init_code_bits, void *user_write_data, void *user_ptr)
Definition: gifformat.c:1846
HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void **ppv)
HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:327
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3273
static HRESULT WINAPI GifDecoder_GetThumbnail(IWICBitmapDecoder *iface, IWICBitmapSource **ppIThumbnail)
Definition: gifformat.c:1271
#define S_OK
Definition: intsafe.h:59
static GpStatus get_decoder_info(IStream *stream, const struct image_codec **result)
Definition: image.c:4237
static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
Definition: gifformat.c:1059
static HRESULT WINAPI GifEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format)
Definition: gifformat.c:2204
static int write_byte(struct output_stream *out, char byte)
Definition: gifformat.c:1889
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT configure_write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, INT width, INT height, double xres, double yres)
Definition: main.c:123
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs)
GLuint in
Definition: glext.h:9616
static previewinfo preview
Definition: print.c:56
unsigned short USHORT
Definition: pedump.c:61
static const MetadataHandlerVtbl APEReader_Vtbl
Definition: gifformat.c:428
#define byte(x, n)
Definition: tomcrypt.h:118
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
Definition: propertybag.c:281
short prefix[LZW_DICT_SIZE]
Definition: gifformat.c:1747
static const IWICMetadataBlockReaderVtbl GifDecoder_BlockVtbl
Definition: gifformat.c:1423
static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:173
#define HeapReAlloc
Definition: compat.h:393
#define E_NOTIMPL
Definition: ddrawi.h:99
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
GLenum GLenum dst
Definition: glext.h:6340
static const MetadataHandlerVtbl GCEReader_Vtbl
Definition: gifformat.c:321
#define GRAPHICS_EXT_FUNC_CODE
Definition: ungif.h:142
struct GifFrameEncode GifFrameEncode
static GifDecoder * impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
Definition: gifformat.c:607
unsigned int UINT
Definition: ndis.h:50
static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface)
Definition: gifformat.c:2160
static int lzw_output_code(struct lzw_state *state, short code)
Definition: gifformat.c:1777
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static int lzw_output_clear_code(struct lzw_state *state)
Definition: gifformat.c:1794
const WCHAR * schema
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GifByteType Blue
Definition: ungif.h:85
static const IWICBitmapEncoderVtbl GifEncoder_Vtbl
Definition: gifformat.c:2358
Definition: reader.h:83
#define MultiByteToWideChar
Definition: compat.h:100
static short lzw_dict_lookup(const struct lzw_state *state, short prefix, unsigned char suffix)
Definition: gifformat.c:1876
static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer, UINT srcwidth, UINT srcheight, INT srcstride, const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
Definition: gifformat.c:750
static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:85
static ULONG WINAPI GifDecoder_AddRef(IWICBitmapDecoder *iface)
Definition: gifformat.c:1049
int ColorCount
Definition: ungif.h:89
INT Width
Definition: wincodec.idl:238
static GifFrameEncode * impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1492
static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, WICRect *rc)
Definition: gifformat.c:1716
static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: gifformat.c:820
int DGifSlurp(GifFileType *GifFile)
Definition: ungif.c:876
unsigned int ULONG
Definition: retypes.h:1
static HRESULT WINAPI GifDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, IEnumUnknown **enumerator)
Definition: gifformat.c:1416
static GifEncoder * impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
Definition: gifformat.c:1474
static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface, UINT *count)
Definition: gifformat.c:891
static HRESULT WINAPI GifFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, IWICBitmapSource **ppIThumbnail)
Definition: gifformat.c:840
static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:660
static const MetadataHandlerVtbl IMDReader_Vtbl
Definition: gifformat.c:243
short next_code
Definition: gifformat.c:1754
static HRESULT WINAPI GifDecoder_GetContainerFormat(IWICBitmapDecoder *iface, GUID *pguidContainerFormat)
Definition: gifformat.c:1169
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
IStream * stream
Definition: gifformat.c:585
HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const WCHAR *root, IWICMetadataQueryReader **out)
static TCHAR * items[]
Definition: page1.c:45
unsigned char suffix[LZW_DICT_SIZE]
Definition: gifformat.c:1748
static HRESULT WINAPI GifDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1022
_Out_ LPRECT prc
Definition: ntgdi.h:1658
static ULONG WINAPI GifDecoder_Block_AddRef(IWICMetadataBlockReader *iface)
Definition: gifformat.c:1345
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:254
static HRESULT WINAPI GifEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
Definition: gifformat.c:2236
UINT32 WICColor
Definition: wincodec.idl:250
#define HeapFree(x, y, z)
Definition: compat.h:394
#define GMEM_MOVEABLE
Definition: winbase.h:291
static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *preview)
Definition: gifformat.c:2262
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1497
static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette *palette)
Definition: gifformat.c:1184
static int write_data(void *user_ptr, void *user_data, int length)
Definition: gifformat.c:1904
static const IWICMetadataBlockReaderVtbl GifFrameDecode_BlockVtbl
Definition: gifformat.c:1011
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GifColorType * Colors
Definition: ungif.h:92
struct lzw_dict dict
Definition: gifformat.c:1753