Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenicoformat.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2009 Vincent Povirk for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 00021 #include <stdarg.h> 00022 00023 #define COBJMACROS 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "wingdi.h" 00028 #include "objbase.h" 00029 #include "wincodec.h" 00030 00031 #include "wincodecs_private.h" 00032 00033 #include "wine/debug.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 00036 00037 #include "pshpack1.h" 00038 00039 typedef struct { 00040 BYTE bWidth; 00041 BYTE bHeight; 00042 BYTE bColorCount; 00043 BYTE bReserved; 00044 WORD wPlanes; 00045 WORD wBitCount; 00046 DWORD dwDIBSize; 00047 DWORD dwDIBOffset; 00048 } ICONDIRENTRY; 00049 00050 typedef struct 00051 { 00052 WORD idReserved; 00053 WORD idType; 00054 WORD idCount; 00055 } ICONHEADER; 00056 00057 #include "poppack.h" 00058 00059 typedef struct { 00060 const IWICBitmapDecoderVtbl *lpVtbl; 00061 LONG ref; 00062 BOOL initialized; 00063 IStream *stream; 00064 ICONHEADER header; 00065 CRITICAL_SECTION lock; /* must be held when accessing stream */ 00066 } IcoDecoder; 00067 00068 typedef struct { 00069 const IWICBitmapFrameDecodeVtbl *lpVtbl; 00070 LONG ref; 00071 ICONDIRENTRY entry; 00072 IcoDecoder *parent; 00073 BYTE *bits; 00074 } IcoFrameDecode; 00075 00076 static HRESULT WINAPI IcoFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, 00077 void **ppv) 00078 { 00079 IcoFrameDecode *This = (IcoFrameDecode*)iface; 00080 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00081 00082 if (!ppv) return E_INVALIDARG; 00083 00084 if (IsEqualIID(&IID_IUnknown, iid) || 00085 IsEqualIID(&IID_IWICBitmapSource, iid) || 00086 IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) 00087 { 00088 *ppv = This; 00089 } 00090 else 00091 { 00092 *ppv = NULL; 00093 return E_NOINTERFACE; 00094 } 00095 00096 IUnknown_AddRef((IUnknown*)*ppv); 00097 return S_OK; 00098 } 00099 00100 static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface) 00101 { 00102 IcoFrameDecode *This = (IcoFrameDecode*)iface; 00103 ULONG ref = InterlockedIncrement(&This->ref); 00104 00105 TRACE("(%p) refcount=%u\n", iface, ref); 00106 00107 return ref; 00108 } 00109 00110 static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface) 00111 { 00112 IcoFrameDecode *This = (IcoFrameDecode*)iface; 00113 ULONG ref = InterlockedDecrement(&This->ref); 00114 00115 TRACE("(%p) refcount=%u\n", iface, ref); 00116 00117 if (ref == 0) 00118 { 00119 IUnknown_Release((IUnknown*)This->parent); 00120 HeapFree(GetProcessHeap(), 0, This->bits); 00121 HeapFree(GetProcessHeap(), 0, This); 00122 } 00123 00124 return ref; 00125 } 00126 00127 static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface, 00128 UINT *puiWidth, UINT *puiHeight) 00129 { 00130 IcoFrameDecode *This = (IcoFrameDecode*)iface; 00131 00132 *puiWidth = This->entry.bWidth ? This->entry.bWidth : 256; 00133 *puiHeight = This->entry.bHeight ? This->entry.bHeight : 256; 00134 00135 TRACE("(%p) -> (%i,%i)\n", iface, *puiWidth, *puiHeight); 00136 00137 return S_OK; 00138 } 00139 00140 static HRESULT WINAPI IcoFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, 00141 WICPixelFormatGUID *pPixelFormat) 00142 { 00143 memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID)); 00144 return S_OK; 00145 } 00146 00147 static HRESULT WINAPI IcoFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, 00148 double *pDpiX, double *pDpiY) 00149 { 00150 FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY); 00151 return E_NOTIMPL; 00152 } 00153 00154 static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, 00155 IWICPalette *pIPalette) 00156 { 00157 TRACE("(%p,%p)\n", iface, pIPalette); 00158 return WINCODEC_ERR_PALETTEUNAVAILABLE; 00159 } 00160 00161 static inline void pixel_set_trans(DWORD* pixel, BOOL transparent) 00162 { 00163 if (transparent) *pixel = 0; 00164 else *pixel |= 0xff000000; 00165 } 00166 00167 static HRESULT IcoFrameDecode_ReadPixels(IcoFrameDecode *This) 00168 { 00169 BITMAPINFOHEADER bih; 00170 DWORD colors[256]; 00171 UINT colorcount=0; 00172 LARGE_INTEGER seek; 00173 ULONG bytesread; 00174 HRESULT hr; 00175 BYTE *tempdata = NULL; 00176 BYTE *bits = NULL; 00177 UINT bitsStride; 00178 UINT bitsSize; 00179 UINT width, height; 00180 00181 width = This->entry.bWidth ? This->entry.bWidth : 256; 00182 height = This->entry.bHeight ? This->entry.bHeight : 256; 00183 00184 /* read the BITMAPINFOHEADER */ 00185 seek.QuadPart = This->entry.dwDIBOffset; 00186 hr = IStream_Seek(This->parent->stream, seek, STREAM_SEEK_SET, NULL); 00187 if (FAILED(hr)) goto fail; 00188 00189 hr = IStream_Read(This->parent->stream, &bih, sizeof(BITMAPINFOHEADER), &bytesread); 00190 if (FAILED(hr) || bytesread != sizeof(BITMAPINFOHEADER)) goto fail; 00191 00192 if (bih.biBitCount <= 8) 00193 { 00194 /* read the palette */ 00195 colorcount = bih.biClrUsed ? bih.biClrUsed : 1 << bih.biBitCount; 00196 00197 hr = IStream_Read(This->parent->stream, colors, sizeof(RGBQUAD)*colorcount, &bytesread); 00198 if (FAILED(hr) || bytesread != sizeof(RGBQUAD)*colorcount) goto fail; 00199 } 00200 00201 bitsStride = width * 4; 00202 bitsSize = bitsStride * height; 00203 00204 /* read the XOR data */ 00205 switch (bih.biBitCount) 00206 { 00207 case 1: 00208 { 00209 UINT xorBytesPerRow = (width+31)/32*4; 00210 UINT xorBytes = xorBytesPerRow * height; 00211 INT xorStride; 00212 BYTE *xorRow; 00213 BYTE *bitsRow; 00214 UINT x, y; 00215 00216 tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes); 00217 if (!tempdata) 00218 { 00219 hr = E_OUTOFMEMORY; 00220 goto fail; 00221 } 00222 00223 hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread); 00224 if (FAILED(hr) || bytesread != xorBytes) goto fail; 00225 00226 if (bih.biHeight > 0) /* bottom-up DIB */ 00227 { 00228 xorStride = -xorBytesPerRow; 00229 xorRow = tempdata + (height-1)*xorBytesPerRow; 00230 } 00231 else /* top-down DIB */ 00232 { 00233 xorStride = xorBytesPerRow; 00234 xorRow = tempdata; 00235 } 00236 00237 bits = HeapAlloc(GetProcessHeap(), 0, bitsSize); 00238 00239 /* palette-map the 1-bit data */ 00240 bitsRow = bits; 00241 for (y=0; y<height; y++) { 00242 BYTE *xorByte=xorRow; 00243 DWORD *bitsPixel=(DWORD*)bitsRow; 00244 for (x=0; x<width; x+=8) { 00245 BYTE xorVal; 00246 xorVal=*xorByte++; 00247 *bitsPixel++ = colors[xorVal>>7]; 00248 if (x+1 < width) *bitsPixel++ = colors[xorVal>>6&1]; 00249 if (x+2 < width) *bitsPixel++ = colors[xorVal>>5&1]; 00250 if (x+3 < width) *bitsPixel++ = colors[xorVal>>4&1]; 00251 if (x+4 < width) *bitsPixel++ = colors[xorVal>>3&1]; 00252 if (x+5 < width) *bitsPixel++ = colors[xorVal>>2&1]; 00253 if (x+6 < width) *bitsPixel++ = colors[xorVal>>1&1]; 00254 if (x+7 < width) *bitsPixel++ = colors[xorVal&1]; 00255 } 00256 xorRow += xorStride; 00257 bitsRow += bitsStride; 00258 } 00259 00260 HeapFree(GetProcessHeap(), 0, tempdata); 00261 break; 00262 } 00263 case 4: 00264 { 00265 UINT xorBytesPerRow = (width+7)/8*4; 00266 UINT xorBytes = xorBytesPerRow * height; 00267 INT xorStride; 00268 BYTE *xorRow; 00269 BYTE *bitsRow; 00270 UINT x, y; 00271 00272 tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes); 00273 if (!tempdata) 00274 { 00275 hr = E_OUTOFMEMORY; 00276 goto fail; 00277 } 00278 00279 hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread); 00280 if (FAILED(hr) || bytesread != xorBytes) goto fail; 00281 00282 if (bih.biHeight > 0) /* bottom-up DIB */ 00283 { 00284 xorStride = -xorBytesPerRow; 00285 xorRow = tempdata + (height-1)*xorBytesPerRow; 00286 } 00287 else /* top-down DIB */ 00288 { 00289 xorStride = xorBytesPerRow; 00290 xorRow = tempdata; 00291 } 00292 00293 bits = HeapAlloc(GetProcessHeap(), 0, bitsSize); 00294 00295 /* palette-map the 4-bit data */ 00296 bitsRow = bits; 00297 for (y=0; y<height; y++) { 00298 BYTE *xorByte=xorRow; 00299 DWORD *bitsPixel=(DWORD*)bitsRow; 00300 for (x=0; x<width; x+=2) { 00301 BYTE xorVal; 00302 xorVal=*xorByte++; 00303 *bitsPixel++ = colors[xorVal>>4]; 00304 if (x+1 < width) *bitsPixel++ = colors[xorVal&0xf]; 00305 } 00306 xorRow += xorStride; 00307 bitsRow += bitsStride; 00308 } 00309 00310 HeapFree(GetProcessHeap(), 0, tempdata); 00311 break; 00312 } 00313 case 8: 00314 { 00315 UINT xorBytesPerRow = (width+3)/4*4; 00316 UINT xorBytes = xorBytesPerRow * height; 00317 INT xorStride; 00318 BYTE *xorRow; 00319 BYTE *bitsRow; 00320 UINT x, y; 00321 00322 tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes); 00323 if (!tempdata) 00324 { 00325 hr = E_OUTOFMEMORY; 00326 goto fail; 00327 } 00328 00329 hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread); 00330 if (FAILED(hr) || bytesread != xorBytes) goto fail; 00331 00332 if (bih.biHeight > 0) /* bottom-up DIB */ 00333 { 00334 xorStride = -xorBytesPerRow; 00335 xorRow = tempdata + (height-1)*xorBytesPerRow; 00336 } 00337 else /* top-down DIB */ 00338 { 00339 xorStride = xorBytesPerRow; 00340 xorRow = tempdata; 00341 } 00342 00343 bits = HeapAlloc(GetProcessHeap(), 0, bitsSize); 00344 00345 /* palette-map the 8-bit data */ 00346 bitsRow = bits; 00347 for (y=0; y<height; y++) { 00348 BYTE *xorByte=xorRow; 00349 DWORD *bitsPixel=(DWORD*)bitsRow; 00350 for (x=0; x<width; x++) 00351 *bitsPixel++ = colors[*xorByte++]; 00352 xorRow += xorStride; 00353 bitsRow += bitsStride; 00354 } 00355 00356 HeapFree(GetProcessHeap(), 0, tempdata); 00357 break; 00358 } 00359 case 24: 00360 { 00361 UINT xorBytesPerRow = (width*3+3)/4*4; 00362 UINT xorBytes = xorBytesPerRow * height; 00363 INT xorStride; 00364 BYTE *xorRow; 00365 BYTE *bitsRow; 00366 UINT x, y; 00367 00368 tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes); 00369 if (!tempdata) 00370 { 00371 hr = E_OUTOFMEMORY; 00372 goto fail; 00373 } 00374 00375 hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread); 00376 if (FAILED(hr) || bytesread != xorBytes) goto fail; 00377 00378 if (bih.biHeight > 0) /* bottom-up DIB */ 00379 { 00380 xorStride = -xorBytesPerRow; 00381 xorRow = tempdata + (height-1)*xorBytesPerRow; 00382 } 00383 else /* top-down DIB */ 00384 { 00385 xorStride = xorBytesPerRow; 00386 xorRow = tempdata; 00387 } 00388 00389 bits = HeapAlloc(GetProcessHeap(), 0, bitsSize); 00390 00391 /* copy BGR->BGRA */ 00392 bitsRow = bits; 00393 for (y=0; y<height; y++) { 00394 BYTE *xorByte=xorRow; 00395 BYTE *bitsByte=bitsRow; 00396 for (x=0; x<width; x++) 00397 { 00398 *bitsByte++ = *xorByte++; /* blue */ 00399 *bitsByte++ = *xorByte++; /* green */ 00400 *bitsByte++ = *xorByte++; /* red */ 00401 bitsByte++; /* alpha */ 00402 } 00403 xorRow += xorStride; 00404 bitsRow += bitsStride; 00405 } 00406 00407 HeapFree(GetProcessHeap(), 0, tempdata); 00408 break; 00409 } 00410 case 32: 00411 { 00412 UINT xorBytesPerRow = width*4; 00413 UINT xorBytes = xorBytesPerRow * height; 00414 00415 bits = HeapAlloc(GetProcessHeap(), 0, xorBytes); 00416 if (!bits) 00417 { 00418 hr = E_OUTOFMEMORY; 00419 goto fail; 00420 } 00421 00422 if (bih.biHeight > 0) /* bottom-up DIB */ 00423 { 00424 /* read the rows backwards so we get a top-down DIB */ 00425 UINT i; 00426 BYTE *xorRow = bits + xorBytesPerRow * (height-1); 00427 00428 for (i=0; i<height; i++) 00429 { 00430 hr = IStream_Read(This->parent->stream, xorRow, xorBytesPerRow, &bytesread); 00431 if (FAILED(hr) || bytesread != xorBytesPerRow) goto fail; 00432 xorRow -= xorBytesPerRow; 00433 } 00434 } 00435 else /* top-down DIB */ 00436 { 00437 hr = IStream_Read(This->parent->stream, bits, xorBytes, &bytesread); 00438 if (FAILED(hr) || bytesread != xorBytes) goto fail; 00439 } 00440 break; 00441 } 00442 default: 00443 FIXME("unsupported bitcount: %u\n", bih.biBitCount); 00444 goto fail; 00445 } 00446 00447 if (bih.biBitCount < 32) 00448 { 00449 /* set alpha data based on the AND mask */ 00450 UINT andBytesPerRow = (width+31)/32*4; 00451 UINT andBytes = andBytesPerRow * height; 00452 INT andStride; 00453 BYTE *andRow; 00454 BYTE *bitsRow; 00455 UINT x, y; 00456 00457 tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes); 00458 if (!tempdata) 00459 { 00460 hr = E_OUTOFMEMORY; 00461 goto fail; 00462 } 00463 00464 hr = IStream_Read(This->parent->stream, tempdata, andBytes, &bytesread); 00465 if (FAILED(hr) || bytesread != andBytes) goto fail; 00466 00467 if (bih.biHeight > 0) /* bottom-up DIB */ 00468 { 00469 andStride = -andBytesPerRow; 00470 andRow = tempdata + (height-1)*andBytesPerRow; 00471 } 00472 else /* top-down DIB */ 00473 { 00474 andStride = andBytesPerRow; 00475 andRow = tempdata; 00476 } 00477 00478 bitsRow = bits; 00479 for (y=0; y<height; y++) { 00480 BYTE *andByte=andRow; 00481 DWORD *bitsPixel=(DWORD*)bitsRow; 00482 for (x=0; x<width; x+=8) { 00483 BYTE andVal=*andByte++; 00484 pixel_set_trans(bitsPixel++, andVal>>7&1); 00485 if (x+1 < width) pixel_set_trans(bitsPixel++, andVal>>6&1); 00486 if (x+2 < width) pixel_set_trans(bitsPixel++, andVal>>5&1); 00487 if (x+3 < width) pixel_set_trans(bitsPixel++, andVal>>4&1); 00488 if (x+4 < width) pixel_set_trans(bitsPixel++, andVal>>3&1); 00489 if (x+5 < width) pixel_set_trans(bitsPixel++, andVal>>2&1); 00490 if (x+6 < width) pixel_set_trans(bitsPixel++, andVal>>1&1); 00491 if (x+7 < width) pixel_set_trans(bitsPixel++, andVal&1); 00492 } 00493 andRow += andStride; 00494 bitsRow += bitsStride; 00495 } 00496 00497 HeapFree(GetProcessHeap(), 0, tempdata); 00498 } 00499 00500 This->bits = bits; 00501 00502 return S_OK; 00503 00504 fail: 00505 HeapFree(GetProcessHeap(), 0, tempdata); 00506 HeapFree(GetProcessHeap(), 0, bits); 00507 if (SUCCEEDED(hr)) hr = E_FAIL; 00508 TRACE("<-- %x\n", hr); 00509 return hr; 00510 } 00511 00512 static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, 00513 const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) 00514 { 00515 IcoFrameDecode *This = (IcoFrameDecode*)iface; 00516 HRESULT hr=S_OK; 00517 UINT width, height, stride; 00518 TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); 00519 00520 EnterCriticalSection(&This->parent->lock); 00521 if (!This->bits) 00522 { 00523 hr = IcoFrameDecode_ReadPixels(This); 00524 } 00525 LeaveCriticalSection(&This->parent->lock); 00526 if (FAILED(hr)) return hr; 00527 00528 width = This->entry.bWidth ? This->entry.bWidth : 256; 00529 height = This->entry.bHeight ? This->entry.bHeight : 256; 00530 stride = width * 4; 00531 00532 return copy_pixels(32, This->bits, width, height, stride, 00533 prc, cbStride, cbBufferSize, pbBuffer); 00534 } 00535 00536 static HRESULT WINAPI IcoFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, 00537 IWICMetadataQueryReader **ppIMetadataQueryReader) 00538 { 00539 TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); 00540 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00541 } 00542 00543 static HRESULT WINAPI IcoFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, 00544 UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) 00545 { 00546 TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); 00547 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00548 } 00549 00550 static HRESULT WINAPI IcoFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, 00551 IWICBitmapSource **ppIThumbnail) 00552 { 00553 TRACE("(%p,%p)\n", iface, ppIThumbnail); 00554 return WINCODEC_ERR_CODECNOTHUMBNAIL; 00555 } 00556 00557 static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = { 00558 IcoFrameDecode_QueryInterface, 00559 IcoFrameDecode_AddRef, 00560 IcoFrameDecode_Release, 00561 IcoFrameDecode_GetSize, 00562 IcoFrameDecode_GetPixelFormat, 00563 IcoFrameDecode_GetResolution, 00564 IcoFrameDecode_CopyPalette, 00565 IcoFrameDecode_CopyPixels, 00566 IcoFrameDecode_GetMetadataQueryReader, 00567 IcoFrameDecode_GetColorContexts, 00568 IcoFrameDecode_GetThumbnail 00569 }; 00570 00571 static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, 00572 void **ppv) 00573 { 00574 IcoDecoder *This = (IcoDecoder*)iface; 00575 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00576 00577 if (!ppv) return E_INVALIDARG; 00578 00579 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid)) 00580 { 00581 *ppv = This; 00582 } 00583 else 00584 { 00585 *ppv = NULL; 00586 return E_NOINTERFACE; 00587 } 00588 00589 IUnknown_AddRef((IUnknown*)*ppv); 00590 return S_OK; 00591 } 00592 00593 static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface) 00594 { 00595 IcoDecoder *This = (IcoDecoder*)iface; 00596 ULONG ref = InterlockedIncrement(&This->ref); 00597 00598 TRACE("(%p) refcount=%u\n", iface, ref); 00599 00600 return ref; 00601 } 00602 00603 static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface) 00604 { 00605 IcoDecoder *This = (IcoDecoder*)iface; 00606 ULONG ref = InterlockedDecrement(&This->ref); 00607 00608 TRACE("(%p) refcount=%u\n", iface, ref); 00609 00610 if (ref == 0) 00611 { 00612 This->lock.DebugInfo->Spare[0] = 0; 00613 DeleteCriticalSection(&This->lock); 00614 if (This->stream) IStream_Release(This->stream); 00615 HeapFree(GetProcessHeap(), 0, This); 00616 } 00617 00618 return ref; 00619 } 00620 00621 static HRESULT WINAPI IcoDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream, 00622 DWORD *pdwCapability) 00623 { 00624 FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability); 00625 return E_NOTIMPL; 00626 } 00627 00628 static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, 00629 WICDecodeOptions cacheOptions) 00630 { 00631 IcoDecoder *This = (IcoDecoder*)iface; 00632 LARGE_INTEGER seek; 00633 HRESULT hr; 00634 ULONG bytesread; 00635 TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); 00636 00637 EnterCriticalSection(&This->lock); 00638 00639 if (This->initialized) 00640 { 00641 hr = WINCODEC_ERR_WRONGSTATE; 00642 goto end; 00643 } 00644 00645 seek.QuadPart = 0; 00646 hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); 00647 if (FAILED(hr)) goto end; 00648 00649 hr = IStream_Read(pIStream, &This->header, sizeof(ICONHEADER), &bytesread); 00650 if (FAILED(hr)) goto end; 00651 if (bytesread != sizeof(ICONHEADER) || 00652 This->header.idReserved != 0 || 00653 This->header.idType != 1) 00654 { 00655 hr = E_FAIL; 00656 goto end; 00657 } 00658 00659 This->initialized = TRUE; 00660 This->stream = pIStream; 00661 IStream_AddRef(pIStream); 00662 00663 end: 00664 00665 LeaveCriticalSection(&This->lock); 00666 00667 return hr; 00668 } 00669 00670 static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface, 00671 GUID *pguidContainerFormat) 00672 { 00673 FIXME("(%p,%p): stub\n", iface, pguidContainerFormat); 00674 return E_NOTIMPL; 00675 } 00676 00677 static HRESULT WINAPI IcoDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, 00678 IWICBitmapDecoderInfo **ppIDecoderInfo) 00679 { 00680 FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo); 00681 return E_NOTIMPL; 00682 } 00683 00684 static HRESULT WINAPI IcoDecoder_CopyPalette(IWICBitmapDecoder *iface, 00685 IWICPalette *pIPalette) 00686 { 00687 TRACE("(%p,%p)\n", iface, pIPalette); 00688 return WINCODEC_ERR_PALETTEUNAVAILABLE; 00689 } 00690 00691 static HRESULT WINAPI IcoDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, 00692 IWICMetadataQueryReader **ppIMetadataQueryReader) 00693 { 00694 TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); 00695 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00696 } 00697 00698 static HRESULT WINAPI IcoDecoder_GetPreview(IWICBitmapDecoder *iface, 00699 IWICBitmapSource **ppIBitmapSource) 00700 { 00701 TRACE("(%p,%p)\n", iface, ppIBitmapSource); 00702 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00703 } 00704 00705 static HRESULT WINAPI IcoDecoder_GetColorContexts(IWICBitmapDecoder *iface, 00706 UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) 00707 { 00708 TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); 00709 return WINCODEC_ERR_UNSUPPORTEDOPERATION; 00710 } 00711 00712 static HRESULT WINAPI IcoDecoder_GetThumbnail(IWICBitmapDecoder *iface, 00713 IWICBitmapSource **ppIThumbnail) 00714 { 00715 TRACE("(%p,%p)\n", iface, ppIThumbnail); 00716 return WINCODEC_ERR_CODECNOTHUMBNAIL; 00717 } 00718 00719 static HRESULT WINAPI IcoDecoder_GetFrameCount(IWICBitmapDecoder *iface, 00720 UINT *pCount) 00721 { 00722 IcoDecoder *This = (IcoDecoder*)iface; 00723 TRACE("(%p,%p)\n", iface, pCount); 00724 00725 if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; 00726 00727 *pCount = This->header.idCount; 00728 TRACE("<-- %u\n", *pCount); 00729 00730 return S_OK; 00731 } 00732 00733 static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, 00734 UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) 00735 { 00736 IcoDecoder *This = (IcoDecoder*)iface; 00737 IcoFrameDecode *result=NULL; 00738 LARGE_INTEGER seek; 00739 HRESULT hr; 00740 ULONG bytesread; 00741 TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); 00742 00743 EnterCriticalSection(&This->lock); 00744 00745 if (!This->initialized) 00746 { 00747 hr = WINCODEC_ERR_NOTINITIALIZED; 00748 goto fail; 00749 } 00750 00751 if (This->header.idCount < index) 00752 { 00753 hr = E_INVALIDARG; 00754 goto fail; 00755 } 00756 00757 result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode)); 00758 if (!result) 00759 { 00760 hr = E_OUTOFMEMORY; 00761 goto fail; 00762 } 00763 00764 result->lpVtbl = &IcoFrameDecode_Vtbl; 00765 result->ref = 1; 00766 result->parent = This; 00767 result->bits = NULL; 00768 00769 /* read the icon entry */ 00770 seek.QuadPart = sizeof(ICONHEADER) + sizeof(ICONDIRENTRY) * index; 00771 hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, 0); 00772 if (FAILED(hr)) goto fail; 00773 00774 hr = IStream_Read(This->stream, &result->entry, sizeof(ICONDIRENTRY), &bytesread); 00775 if (FAILED(hr) || bytesread != sizeof(ICONDIRENTRY)) goto fail; 00776 00777 IWICBitmapDecoder_AddRef(iface); 00778 00779 *ppIBitmapFrame = (IWICBitmapFrameDecode*)result; 00780 00781 LeaveCriticalSection(&This->lock); 00782 00783 return S_OK; 00784 00785 fail: 00786 LeaveCriticalSection(&This->lock); 00787 HeapFree(GetProcessHeap(), 0, result); 00788 if (SUCCEEDED(hr)) hr = E_FAIL; 00789 TRACE("<-- %x\n", hr); 00790 return hr; 00791 } 00792 00793 static const IWICBitmapDecoderVtbl IcoDecoder_Vtbl = { 00794 IcoDecoder_QueryInterface, 00795 IcoDecoder_AddRef, 00796 IcoDecoder_Release, 00797 IcoDecoder_QueryCapability, 00798 IcoDecoder_Initialize, 00799 IcoDecoder_GetContainerFormat, 00800 IcoDecoder_GetDecoderInfo, 00801 IcoDecoder_CopyPalette, 00802 IcoDecoder_GetMetadataQueryReader, 00803 IcoDecoder_GetPreview, 00804 IcoDecoder_GetColorContexts, 00805 IcoDecoder_GetThumbnail, 00806 IcoDecoder_GetFrameCount, 00807 IcoDecoder_GetFrame 00808 }; 00809 00810 HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) 00811 { 00812 IcoDecoder *This; 00813 HRESULT ret; 00814 00815 TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv); 00816 00817 *ppv = NULL; 00818 00819 if (pUnkOuter) return CLASS_E_NOAGGREGATION; 00820 00821 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoDecoder)); 00822 if (!This) return E_OUTOFMEMORY; 00823 00824 This->lpVtbl = &IcoDecoder_Vtbl; 00825 This->ref = 1; 00826 This->stream = NULL; 00827 This->initialized = FALSE; 00828 InitializeCriticalSection(&This->lock); 00829 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock"); 00830 00831 ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); 00832 IUnknown_Release((IUnknown*)This); 00833 00834 return ret; 00835 } Generated on Fri May 25 2012 04:24:55 for ReactOS by
1.7.6.1
|