ReactOS 0.4.16-dev-197-g92996da
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
77static 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
533static IStream *create_stream(const void *data, int data_size)
534{
535 HRESULT hr;
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
548 return FAILED(hr) ? NULL : stream;
549}
550
551static 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;
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
582typedef struct {
586 BYTE LSD_data[13]; /* Logical Screen Descriptor */
592} GifDecoder;
593
594typedef 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
750static 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;
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
847static 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;
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 {
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
1011static 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;
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
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);
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)
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
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
1321static 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
1423static const IWICMetadataBlockReaderVtbl GifDecoder_BlockVtbl =
1424{
1432};
1433
1435{
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
1462typedef struct GifEncoder
1463{
1473
1475{
1476 return CONTAINING_RECORD(iface, GifEncoder, IWICBitmapEncoder_iface);
1477}
1478
1479typedef struct GifFrameEncode
1480{
1486 double xres, yres;
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);
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
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
1746{
1748 unsigned char suffix[LZW_DICT_SIZE];
1749};
1750
1752{
1755 unsigned bits_buf;
1757 int (*user_write_data)(void *user_ptr, void *data, int length);
1759};
1760
1762{
1763 unsigned len;
1764 const BYTE *in;
1765};
1766
1768{
1769 struct
1770 {
1771 unsigned char len;
1772 char data[255];
1775};
1776
1777static 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
1794static inline int lzw_output_clear_code(struct lzw_state *state)
1795{
1796 return lzw_output_code(state, state->clear_code);
1797}
1798
1799static inline int lzw_output_eof_code(struct lzw_state *state)
1800{
1801 return lzw_output_code(state, state->eof_code);
1802}
1803
1804static 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
1832static 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
1846static 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
1859static 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
1876static 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
1889static 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
1904static 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
1918static 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
1933static 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
1945static 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;
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
2115static 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;
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
2358static const IWICBitmapEncoderVtbl GifEncoder_Vtbl =
2359{
2373};
2374
2376{
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 int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static previewinfo preview
Definition: print.c:56
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
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:1700
const WCHAR * vendor
Definition: db.cpp:872
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
@ VT_LPSTR
Definition: compat.h:2324
@ VT_UI2
Definition: compat.h:2312
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_BOOL
Definition: compat.h:2306
@ VT_VECTOR
Definition: compat.h:2340
@ VT_UI1
Definition: compat.h:2311
static GpStatus get_decoder_info(IStream *stream, const struct image_codec **result)
Definition: image.c:4285
static const WCHAR gif_extension[]
Definition: image.c:4787
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
#define byte(x, n)
Definition: tomcrypt.h:118
HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:2375
static HRESULT WINAPI GifFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, IWICBitmapSource **ppIThumbnail)
Definition: gifformat.c:840
static HRESULT WINAPI GifEncoder_Commit(IWICBitmapEncoder *iface)
Definition: gifformat.c:2326
static HRESULT WINAPI GifFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double xres, double yres)
Definition: gifformat.c:1596
static HRESULT WINAPI GifFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette *palette)
Definition: gifformat.c:1649
static HRESULT WINAPI GifDecoder_GetPreview(IWICBitmapDecoder *iface, IWICBitmapSource **ppIBitmapSource)
Definition: gifformat.c:1257
static HRESULT WINAPI GifDecoder_GetContainerFormat(IWICBitmapDecoder *iface, GUID *pguidContainerFormat)
Definition: gifformat.c:1169
HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:327
static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
Definition: gifformat.c:1294
static HRESULT WINAPI GifDecoder_Block_GetCount(IWICMetadataBlockReader *iface, UINT *count)
Definition: gifformat.c:1368
static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface)
Definition: gifformat.c:2160
static ULONG WINAPI GifDecoder_Block_Release(IWICMetadataBlockReader *iface)
Definition: gifformat.c:1351
static const IWICMetadataBlockReaderVtbl GifFrameDecode_BlockVtbl
Definition: gifformat.c:1011
static GifDecoder * impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
Definition: gifformat.c:602
static HRESULT WINAPI GifFrameDecode_GetSize(IWICBitmapFrameDecode *iface, UINT *puiWidth, UINT *puiHeight)
Definition: gifformat.c:676
static const IWICMetadataBlockReaderVtbl GifDecoder_BlockVtbl
Definition: gifformat.c:1423
static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface)
Definition: gifformat.c:2151
HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:249
static IStream * create_stream(const void *data, int data_size)
Definition: gifformat.c:533
static HRESULT WINAPI GifEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format)
Definition: gifformat.c:2204
static HRESULT WINAPI GifDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, IEnumUnknown **enumerator)
Definition: gifformat.c:1416
static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:254
static int lzw_dict_add(struct lzw_state *state, short prefix, unsigned char suffix)
Definition: gifformat.c:1859
static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:650
static HRESULT WINAPI GifEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
Definition: gifformat.c:2212
static HRESULT WINAPI GifFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, WICPixelFormatGUID *pPixelFormat)
Definition: gifformat.c:688
static const MetadataHandlerVtbl LSDReader_Vtbl
Definition: gifformat.c:162
static HRESULT WINAPI GifEncoder_SetColorContexts(IWICBitmapEncoder *iface, UINT count, IWICColorContext **context)
Definition: gifformat.c:2230
static HRESULT WINAPI GifDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *guid)
Definition: gifformat.c:1357
static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl
Definition: gifformat.c:2115
static HRESULT WINAPI GifEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *thumbnail)
Definition: gifformat.c:2256
static ULONG WINAPI GifFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface)
Definition: gifformat.c:868
static GifEncoder * impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
Definition: gifformat.c:1474
static HRESULT WINAPI GifDecoder_GetThumbnail(IWICBitmapDecoder *iface, IWICBitmapSource **ppIThumbnail)
Definition: gifformat.c:1271
static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1497
static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1524
static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, IWICMetadataQueryWriter **writer)
Definition: gifformat.c:2109
HRESULT GifDecoder_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:1434
static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:85
HRESULT APEReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:434
static HRESULT WINAPI GifEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
Definition: gifformat.c:2236
static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, void **ppv)
Definition: gifformat.c:622
static int write_byte(struct output_stream *out, char byte)
Definition: gifformat.c:1889
static short lzw_dict_lookup(const struct lzw_state *state, short prefix, unsigned char suffix)
Definition: gifformat.c:1876
static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1515
static ULONG WINAPI GifFrameDecode_Block_Release(IWICMetadataBlockReader *iface)
Definition: gifformat.c:874
static GifDecoder * impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
Definition: gifformat.c:607
static HRESULT WINAPI GifFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *guid)
Definition: gifformat.c:880
static const IWICBitmapDecoderVtbl GifDecoder_Vtbl
Definition: gifformat.c:1321
static HRESULT WINAPI GifDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **reader)
Definition: gifformat.c:1381
static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette *palette)
Definition: gifformat.c:1184
static HRESULT WINAPI GifFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, void **ppv)
Definition: gifformat.c:861
static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: gifformat.c:820
static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:332
static HRESULT WINAPI GifFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *options)
Definition: gifformat.c:1541
static HRESULT WINAPI GifFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, IWICBitmapSource *thumbnail)
Definition: gifformat.c:1669
static HRESULT WINAPI GifEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, IWICMetadataQueryWriter **writer)
Definition: gifformat.c:2352
static void lzw_dict_reset(struct lzw_state *state)
Definition: gifformat.c:1832
static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **frame, IPropertyBag2 **options)
Definition: gifformat.c:2268
static HRESULT WINAPI GifDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, DWORD *capability)
Definition: gifformat.c:1081
static ULONG WINAPI GifDecoder_Block_AddRef(IWICMetadataBlockReader *iface)
Definition: gifformat.c:1345
static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:173
static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface, UINT *count)
Definition: gifformat.c:891
static int lzw_output_eof_code(struct lzw_state *state)
Definition: gifformat.c:1799
static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count)
Definition: gifformat.c:439
static LPWSTR strdupAtoW(const char *src)
Definition: gifformat.c:77
static HRESULT WINAPI GifDecoder_GetFrameCount(IWICBitmapDecoder *iface, UINT *pCount)
Definition: gifformat.c:1278
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, IEnumUnknown **enumerator)
Definition: gifformat.c:1004
static GifFrameDecode * impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:612
static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, double *pDpiX, double *pDpiY)
Definition: gifformat.c:696
static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len)
Definition: gifformat.c:1099
static HRESULT WINAPI GifDecoder_GetColorContexts(IWICBitmapDecoder *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: gifformat.c:1264
static HRESULT WINAPI GifFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
Definition: gifformat.c:800
static HRESULT gif_compress(IStream *out_stream, const BYTE *in_data, ULONG in_size)
Definition: gifformat.c:1945
HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:168
static const MetadataHandlerVtbl IMDReader_Vtbl
Definition: gifformat.c:243
static HRESULT create_metadata_reader(const void *data, int data_size, class_constructor constructor, IWICMetadataReader **reader)
Definition: gifformat.c:551
static GifFrameDecode * frame_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
Definition: gifformat.c:617
static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *preview)
Definition: gifformat.c:2262
HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv)
Definition: gifformat.c:528
static HRESULT WINAPI GifEncoder_Initialize(IWICBitmapEncoder *iface, IStream *stream, WICBitmapEncoderCacheOption option)
Definition: gifformat.c:2178
static const MetadataHandlerVtbl GCEReader_Vtbl
Definition: gifformat.c:321
static int flush_output_data(void *user_ptr)
Definition: gifformat.c:1918
static HRESULT WINAPI GifFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, UINT count, IWICColorContext **context)
Definition: gifformat.c:1643
static HRESULT WINAPI GifDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1022
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 const IWICBitmapEncoderVtbl GifEncoder_Vtbl
Definition: gifformat.c:2358
static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface)
Definition: gifformat.c:660
static int lzw_flush_bits(struct lzw_state *state)
Definition: gifformat.c:1804
#define LZW_DICT_SIZE
Definition: gifformat.c:1743
static HRESULT WINAPI GifDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, void **ppv)
Definition: gifformat.c:1338
static HRESULT WINAPI GifFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *format)
Definition: gifformat.c:1619
static const MetadataHandlerVtbl APEReader_Vtbl
Definition: gifformat.c:428
static void lzw_state_init(struct lzw_state *state, short init_code_bits, void *user_write_data, void *user_ptr)
Definition: gifformat.c:1846
static const MetadataHandlerVtbl GifCommentReader_Vtbl
Definition: gifformat.c:522
static HRESULT WINAPI GifDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, IWICBitmapDecoderInfo **ppIDecoderInfo)
Definition: gifformat.c:1176
static HRESULT WINAPI GifDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, IWICMetadataQueryReader **ppIMetadataQueryReader)
Definition: gifformat.c:1245
static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, WICDecodeOptions cacheOptions)
Definition: gifformat.c:1115
static HRESULT create_IMD_metadata_reader(GifFrameDecode *This, IWICMetadataReader **reader)
Definition: gifformat.c:904
static HRESULT WINAPI GifEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, void **ppv)
Definition: gifformat.c:2133
static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:2004
static int lzw_output_clear_code(struct lzw_state *state)
Definition: gifformat.c:1794
static int read_byte(struct input_stream *in, unsigned char *byte)
Definition: gifformat.c:1933
static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
Definition: gifformat.c:1059
static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT width, UINT height)
Definition: gifformat.c:1563
static HRESULT WINAPI GifFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lines, UINT stride, UINT size, BYTE *pixels)
Definition: gifformat.c:1675
static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, WICRect *rc)
Definition: gifformat.c:1716
static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **reader)
Definition: gifformat.c:952
static GifFrameEncode * impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
Definition: gifformat.c:1492
static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl
Definition: gifformat.c:847
static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
Definition: gifformat.c:833
static int lzw_output_code(struct lzw_state *state, short code)
Definition: gifformat.c:1777
static ULONG WINAPI GifDecoder_AddRef(IWICBitmapDecoder *iface)
Definition: gifformat.c:1049
static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette)
Definition: gifformat.c:710
HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
Definition: info.c:2075
HRESULT write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, UINT bpp, INT width, INT height)
Definition: main.c:155
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
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
Definition: propertybag.c:281
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLsizei stride
Definition: glext.h:5848
GLenum src
Definition: glext.h:6340
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define debugstr_guid
Definition: kernel32.h:35
if(dx< 0)
Definition: linetemp.h:194
HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void **ppv)
HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void **ppv)
const WCHAR * schema
HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const WCHAR *root, IWICMetadataQueryReader **out)
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:100
static HPALETTE palette
Definition: clipboard.c:1345
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
static TCHAR * items[]
Definition: page1.c:45
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static FILE * out
Definition: regtests2xml.c:44
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
GifColorType * Colors
Definition: ungif.h:92
int ColorCount
Definition: ungif.h:89
char * Bytes
Definition: ungif.h:105
int ByteCount
Definition: ungif.h:104
int Function
Definition: ungif.h:103
GifByteType Blue
Definition: ungif.h:85
GifByteType Green
Definition: ungif.h:85
GifByteType Red
Definition: ungif.h:85
CRITICAL_SECTION lock
Definition: gifformat.c:591
BOOL initialized
Definition: gifformat.c:588
IWICBitmapDecoder IWICBitmapDecoder_iface
Definition: gifformat.c:583
GifFileType * gif
Definition: gifformat.c:589
LONG ref
Definition: gifformat.c:587
UINT current_frame
Definition: gifformat.c:590
IWICMetadataBlockReader IWICMetadataBlockReader_iface
Definition: gifformat.c:584
IStream * stream
Definition: gifformat.c:585
IWICBitmapEncoder IWICBitmapEncoder_iface
Definition: gifformat.c:1464
CRITICAL_SECTION lock
Definition: gifformat.c:1467
BOOL committed
Definition: gifformat.c:1468
UINT n_frames
Definition: gifformat.c:1469
UINT colors
Definition: gifformat.c:1471
WICColor palette[256]
Definition: gifformat.c:1470
BOOL initialized
Definition: gifformat.c:1468
IStream * stream
Definition: gifformat.c:1466
BOOL info_written
Definition: gifformat.c:1468
void * UserData
Definition: ungif.h:124
SavedImage * frame
Definition: gifformat.c:598
IWICMetadataBlockReader IWICMetadataBlockReader_iface
Definition: gifformat.c:596
GifDecoder * parent
Definition: gifformat.c:599
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface
Definition: gifformat.c:595
GifEncoder * encoder
Definition: gifformat.c:1483
WICColor palette[256]
Definition: gifformat.c:1487
IWICBitmapFrameEncode IWICBitmapFrameEncode_iface
Definition: gifformat.c:1481
BYTE * image_data
Definition: gifformat.c:1489
INT Height
Definition: wincodec.idl:301
INT Width
Definition: wincodec.idl:300
Definition: inflate.c:139
Definition: http.c:7252
Definition: format.c:58
const BYTE * in
Definition: gifformat.c:1764
unsigned len
Definition: gifformat.c:1763
short prefix[LZW_DICT_SIZE]
Definition: gifformat.c:1747
unsigned char suffix[LZW_DICT_SIZE]
Definition: gifformat.c:1748
int bits_count
Definition: gifformat.c:1756
unsigned bits_buf
Definition: gifformat.c:1755
short init_code_bits
Definition: gifformat.c:1754
void * user_ptr
Definition: gifformat.c:1758
int(* user_write_data)(void *user_ptr, void *data, int length)
Definition: gifformat.c:1757
short eof_code
Definition: gifformat.c:1754
short clear_code
Definition: gifformat.c:1754
struct lzw_dict dict
Definition: gifformat.c:1753
short code_bits
Definition: gifformat.c:1754
short next_code
Definition: gifformat.c:1754
Definition: getopt.h:109
struct output_stream::@594 gif_block
unsigned char len
Definition: gifformat.c:1771
IStream * out
Definition: gifformat.c:1774
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
eMaj lines
Definition: tritemp.h:206
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
GifFileType * DGifOpen(void *userData, InputFunc readFunc)
Definition: ungif.c:993
int DGifCloseFile(GifFileType *GifFile)
Definition: ungif.c:1047
int DGifSlurp(GifFileType *GifFile)
Definition: ungif.c:876
unsigned char GifByteType
Definition: ungif.h:80
#define COMMENT_EXT_FUNC_CODE
Definition: ungif.h:141
#define APPLICATION_EXT_FUNC_CODE
Definition: ungif.h:144
#define GRAPHICS_EXT_FUNC_CODE
Definition: ungif.h:142
int GifWord
Definition: ungif.h:82
#define GIF_ERROR
Definition: ungif.h:55
Definition: pdh_main.c:94
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
int ret
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define GMEM_MOVEABLE
Definition: winbase.h:319
WICBitmapEncoderCacheOption
Definition: wincodec.idl:69
WICDecodeOptions
Definition: wincodec.idl:27
@ WICDecodeMetadataCacheOnDemand
Definition: wincodec.idl:28
UINT32 WICColor
Definition: wincodec.idl:312
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
Definition: wincodec.idl:50
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
Definition: wincodec.idl:51
@ WICBitmapDecoderCapabilityCanDecodeAllImages
Definition: wincodec.idl:49
static const char * debug_wic_rect(const WICRect *rect)
HRESULT(* class_constructor)(REFIID, void **)
@ WICPersistOptionDefault
Definition: wincodecsdk.idl:23
#define WINAPI
Definition: msvc.h:6
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3281
#define WINCODEC_ERR_UNSUPPORTEDOPERATION
Definition: winerror.h:3308
#define WINCODEC_ERR_NOTINITIALIZED
Definition: winerror.h:3285
#define E_NOINTERFACE
Definition: winerror.h:2364
#define WINCODEC_ERR_CODECNOTHUMBNAIL
Definition: winerror.h:3291
#define WINCODEC_ERR_FRAMEMISSING
Definition: winerror.h:3301
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193