/*********************************************************************** * decode png file * const char *file_path = path to png file e.g. "/dev_hdd0/test.png" ***********************************************************************/ Buffer load_png(const char *file_path) { Buffer tmp; png_dec_info dec_ctx; // decryption handles void *buf_addr = NULL; // buffer for decoded png data // create png decoder create_decoder(&dec_ctx); // open png stream open_png(&dec_ctx, file_path); // set decode parameter set_dec_param(&dec_ctx); // alloc target buffer buf_addr = mem_alloc(png_w * png_h * 4); // decode png stream, into target buffer decode_png_stream(&dec_ctx, buf_addr); // close png stream PngDecClose(dec_ctx.main_h, dec_ctx.sub_h); // destroy png decoder PngDecDestroy(dec_ctx.main_h); // store png values tmp.addr = (uint32_t*)buf_addr; tmp.w = png_w; tmp.h = png_h; return tmp; }
static void test_global_gif_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; GUID format; UINT count, ret; WICColor color[256]; decoder = create_decoder(gif_global_palette, sizeof(gif_global_palette)); ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
AbstractDecoder* Decoder::get_shared_instance() { assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(), "Require DecoderLock to enter"); if (_shared_decoder == NULL) { _shared_decoder = create_decoder(); } return _shared_decoder; }
static void test_color_formats(void) { static const struct { char bit_depth, color_type; const GUID *format; } td[] = { /* 2 - PNG_COLOR_TYPE_RGB */ { 8, 2, &GUID_WICPixelFormat24bppBGR }, /* 0 - PNG_COLOR_TYPE_GRAY */ { 1, 0, &GUID_WICPixelFormatBlackWhite }, { 2, 0, &GUID_WICPixelFormat2bppGray }, { 4, 0, &GUID_WICPixelFormat4bppGray }, { 8, 0, &GUID_WICPixelFormat8bppGray }, { 16, 0, &GUID_WICPixelFormat16bppGray }, }; char buf[sizeof(png_1x1_data)]; HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; GUID format; int i; for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; decoder = create_decoder(buf, sizeof(buf)); ok(decoder != NULL, "Failed to load PNG image data\n"); if (!decoder) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format)); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); } }
static void test_png_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; GUID format; UINT count, ret; WICColor color[256]; decoder = create_decoder(png_PLTE_tRNS, sizeof(png_PLTE_tRNS)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat1bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
static void test_local_gif_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICPalette *palette; WICBitmapPaletteType type; GUID format; UINT count, ret, i; WICColor color[256]; decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette)); ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr); if (hr == S_OK) { type = -1; hr = IWICPalette_GetType(palette, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); for (i = 2; i < 256; i++) ok(color[i] == 0xff000000, "expected 0xff000000, got %#x\n", color[i]); } /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == S_OK, "CopyPalette error %#x\n", hr); hr = IWICPalette_GetColorCount(palette, &count); ok(hr == S_OK, "GetColorCount error %#x\n", hr); ok(count == 4, "expected 4, got %u\n", count); type = -1; hr = IWICPalette_GetType(palette, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColors(palette, count, color, &ret); ok(hr == S_OK, "GetColors error %#x\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]); ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
/* ================================================================= MPEG decompression ================================================================= */ qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize ) { mpeg_t mpeg; size_t pos = 0; size_t bytesWrite = 0; // load the file if( !buffer || filesize < FRAME_SIZE ) return false; // couldn't create decoder if( !create_decoder( &mpeg )) return false; // trying to read header if( !read_mpeg_header( &mpeg, buffer, FRAME_SIZE, filesize )) { MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name ); close_decoder( &mpeg ); return false; } sound.channels = mpeg.channels; sound.rate = mpeg.rate; sound.width = 2; // always 16-bit PCM sound.loopstart = -1; sound.size = ( sound.channels * sound.rate * sound.width ) * ( mpeg.play_time / 1000 ); // in bytes pos += FRAME_SIZE; // evaluate pos if( !sound.size ) { // bad mpeg file ? MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name ); close_decoder( &mpeg ); return false; } sound.type = WF_PCMDATA; sound.wav = (byte *)Mem_Alloc( host.soundpool, sound.size ); // decompress mpg into pcm wav format while( bytesWrite < sound.size ) { int outsize; if( read_mpeg_stream( &mpeg, NULL, 0 ) != MP3_OK ) { char *data = (char *)buffer + pos; int bufsize; // if there are no bytes remainig so we can decompress the new frame if( pos + FRAME_SIZE > filesize ) bufsize = ( filesize - pos ); else bufsize = FRAME_SIZE; pos += bufsize; if( read_mpeg_stream( &mpeg, data, bufsize ) != MP3_OK ) break; // there was end of the stream } if( bytesWrite + mpeg.outsize > sound.size ) outsize = ( sound.size - bytesWrite ); else outsize = mpeg.outsize; Q_memcpy( &sound.wav[bytesWrite], mpeg.out, outsize ); bytesWrite += outsize; } sound.samples = bytesWrite / ( sound.width * sound.channels ); close_decoder( &mpeg ); return true; }
/* ================= Stream_OpenMPG ================= */ stream_t *Stream_OpenMPG( const char *filename ) { mpeg_t *mpegFile; stream_t *stream; file_t *file; long filesize, read_len; char tempbuff[FRAME_SIZE]; file = FS_Open( filename, "rb", false ); if( !file ) return NULL; filesize = FS_FileLength( file ); if( filesize < FRAME_SIZE ) { MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename ); FS_Close( file ); return NULL; } // at this point we have valid stream stream = Mem_Alloc( host.soundpool, sizeof( stream_t )); stream->file = file; stream->pos = 0; mpegFile = Mem_Alloc( host.soundpool, sizeof( mpeg_t )); // couldn't create decoder if( !create_decoder( mpegFile )) { MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder\n" ); Mem_Free( mpegFile ); Mem_Free( stream ); FS_Close( file ); return NULL; } read_len = FS_Read( file, tempbuff, sizeof( tempbuff )); if( read_len < sizeof( tempbuff )) { MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename ); close_decoder( mpegFile ); Mem_Free( mpegFile ); Mem_Free( stream ); FS_Close( file ); return NULL; } // trying to read header if( !read_mpeg_header( mpegFile, tempbuff, sizeof( tempbuff ), filesize )) { MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", filename ); close_decoder( mpegFile ); Mem_Free( mpegFile ); Mem_Free( stream ); FS_Close( file ); return NULL; } stream->buffsize = 0; // how many samples left from previous frame stream->channels = mpegFile->channels; stream->pos += mpegFile->outsize; stream->rate = mpegFile->rate; stream->width = 2; // always 16 bit stream->ptr = mpegFile; stream->type = WF_MPGDATA; return stream; }
static void test_color_contexts(void) { HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; IWICColorContext *context; WICColorContextType type; UINT count, colorspace, size; WCHAR *tmpfile; BYTE *buffer; BOOL ret; decoder = create_decoder(png_no_color_profile, sizeof(png_no_color_profile)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; /* global color context */ hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, NULL); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); ok(!count, "unexpected count %u\n", count); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); decoder = create_decoder(png_color_profile, sizeof(png_color_profile)); ok(decoder != 0, "Failed to load PNG image data\n"); if (!decoder) return; /* global color context */ count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICImagingFactory_CreateColorContext(factory, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); ok(hr == S_OK, "CreateColorContext error %#x\n", hr); hr = IWICColorContext_GetType(context, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextUninitialized, "unexpected type %u\n", type); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); ok(!size, "unexpected size %u\n", size); hr = IWICColorContext_GetExifColorSpace(context, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 0); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 2); ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 2, "unexpected color space %u\n", colorspace); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); ok(!size, "unexpected size %u\n", size); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextExifColorSpace, "unexpected type %u\n", type); hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#x\n", hr); IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); ok(hr == S_OK, "CreateColorContext error %#x\n", hr); count = 1; hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); ok(hr == S_OK, "GetColorContexts error %#x\n", hr); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); tmpfile = save_profile( buffer, size ); HeapFree(GetProcessHeap(), 0, buffer); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); if (tmpfile) { hr = IWICColorContext_InitializeFromFilename(context, NULL); ok(hr == E_INVALIDARG, "InitializeFromFilename error %#x\n", hr); hr = IWICColorContext_InitializeFromFilename(context, tmpfile); ok(hr == S_OK, "InitializeFromFilename error %#x\n", hr); ret = DeleteFileW(tmpfile); ok(ret, "DeleteFileW failed %u\n", GetLastError()); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); ok(hr == S_OK, "GetType error %#x\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, tmpfile); } IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); }
AbstractDecoder* Decoder::get_error_handler_instance() { if (_error_handler_decoder == NULL) { _error_handler_decoder = create_decoder(); } return _error_handler_decoder; }
static void test_color_formats(void) { static const struct { char bit_depth, color_type; const GUID *format; const GUID *format_PLTE; const GUID *format_PLTE_tRNS; BOOL todo; BOOL todo_load; } td[] = { /* 2 - PNG_COLOR_TYPE_RGB */ { 1, 2, NULL, NULL, NULL }, { 2, 2, NULL, NULL, NULL }, { 4, 2, NULL, NULL, NULL }, { 8, 2, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat24bppBGR }, /* libpng refuses to load our test image complaining about extra compressed data, * but libpng is still able to load the image with other combination of type/depth * making RGB 16 bpp case special for some reason. Therefore todo = TRUE. */ { 16, 2, &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat48bppRGB, TRUE, TRUE }, { 24, 2, NULL, NULL, NULL }, { 32, 2, NULL, NULL, NULL }, /* 0 - PNG_COLOR_TYPE_GRAY */ { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed, TRUE }, { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed, TRUE }, { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed, TRUE }, { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed, TRUE }, { 16, 0, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat64bppRGBA, TRUE }, { 24, 0, NULL, NULL, NULL }, { 32, 0, NULL, NULL, NULL }, /* 3 - PNG_COLOR_TYPE_PALETTE */ { 1, 3, &GUID_WICPixelFormat1bppIndexed, &GUID_WICPixelFormat1bppIndexed, &GUID_WICPixelFormat1bppIndexed }, { 2, 3, &GUID_WICPixelFormat2bppIndexed, &GUID_WICPixelFormat2bppIndexed, &GUID_WICPixelFormat2bppIndexed }, { 4, 3, &GUID_WICPixelFormat4bppIndexed, &GUID_WICPixelFormat4bppIndexed, &GUID_WICPixelFormat4bppIndexed }, { 8, 3, &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat8bppIndexed }, { 16, 3, NULL, NULL, NULL }, { 24, 3, NULL, NULL, NULL }, { 32, 3, NULL, NULL, NULL }, }; char buf[sizeof(png_1x1_data)]; HRESULT hr; IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *frame; GUID format; int i, PLTE_off = 0, tRNS_off = 0; memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); for (i = 0; i < sizeof(png_1x1_data) - 4; i++) { if (!memcmp(buf + i, "tRNS", 4)) tRNS_off = i; else if (!memcmp(buf + i, "PLTE", 4)) PLTE_off = i; } ok(PLTE_off && tRNS_off, "PLTE offset %d, tRNS offset %d\n", PLTE_off, tRNS_off); if (!PLTE_off || !tRNS_off) return; /* In order to test the image data with and without PLTE and tRNS chunks * it's been decided to simply sero out the chunk id for testing puposes, * and under Windows such images get loaded just fine. But unfortunately * libpng refuses to load such images complaining about unknown chunk type. * A workaround for this libpng limitation is to mark the "disabled" chunks * with tEXt id. */ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { /* with the tRNS and PLTE chunks */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_1; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "PLTE+tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_1: /* without the tRNS chunk */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + tRNS_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_2; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format_PLTE), "PLTE: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_2: /* without the tRNS and PLTE chunks */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + PLTE_off, "tEXt", 4); memcpy(buf + tRNS_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_3; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); next_3: /* without the PLTE chunk */ memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); buf[24] = td[i].bit_depth; buf[25] = td[i].color_type; memcpy(buf + PLTE_off, "tEXt", 4); hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); } }