static HRESULT WINAPI JpegEncoder_Initialize(IWICBitmapEncoder *iface, IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) { JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); jmp_buf jmpbuf; TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); EnterCriticalSection(&This->lock); if (This->initialized) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } pjpeg_std_error(&This->jerr); This->jerr.error_exit = error_exit_fn; This->jerr.emit_message = emit_message_fn; This->cinfo.err = &This->jerr; This->cinfo.client_data = jmpbuf; if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); return E_FAIL; } pjpeg_CreateCompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_compress_struct)); This->stream = pIStream; IStream_AddRef(pIStream); This->dest_mgr.next_output_byte = This->dest_buffer; This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); This->dest_mgr.init_destination = dest_mgr_init_destination; This->dest_mgr.empty_output_buffer = dest_mgr_empty_output_buffer; This->dest_mgr.term_destination = dest_mgr_term_destination; This->cinfo.dest = &This->dest_mgr; This->initialized = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, WICDecodeOptions cacheOptions) { JpegDecoder *This = (JpegDecoder*)iface; int ret; LARGE_INTEGER seek; jmp_buf jmpbuf; TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); EnterCriticalSection(&This->lock); if (This->cinfo_initialized) { LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } pjpeg_std_error(&This->jerr); This->jerr.error_exit = error_exit_fn; This->jerr.emit_message = emit_message_fn; This->cinfo.err = &This->jerr; This->cinfo.client_data = &jmpbuf; if (setjmp(jmpbuf)) { LeaveCriticalSection(&This->lock); return E_FAIL; } pjpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); This->cinfo_initialized = TRUE; This->stream = pIStream; IStream_AddRef(pIStream); seek.QuadPart = 0; IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL); This->source_mgr.bytes_in_buffer = 0; This->source_mgr.init_source = source_mgr_init_source; This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer; This->source_mgr.skip_input_data = source_mgr_skip_input_data; This->source_mgr.resync_to_restart = pjpeg_resync_to_restart; This->source_mgr.term_source = source_mgr_term_source; This->cinfo.src = &This->source_mgr; ret = pjpeg_read_header(&This->cinfo, TRUE); if (ret != JPEG_HEADER_OK) { WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); LeaveCriticalSection(&This->lock); return E_FAIL; } switch (This->cinfo.jpeg_color_space) { case JCS_GRAYSCALE: This->cinfo.out_color_space = JCS_GRAYSCALE; break; case JCS_RGB: case JCS_YCbCr: This->cinfo.out_color_space = JCS_RGB; break; case JCS_CMYK: case JCS_YCCK: This->cinfo.out_color_space = JCS_CMYK; break; default: ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space); LeaveCriticalSection(&This->lock); return E_FAIL; } if (!pjpeg_start_decompress(&This->cinfo)) { ERR("jpeg_start_decompress failed\n"); LeaveCriticalSection(&This->lock); return E_FAIL; } This->initialized = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
TW_UINT16 _get_gphoto2_file_as_DIB( const char *folder, const char *filename, CameraFileType type, HWND hwnd, HBITMAP *hDIB ) { const unsigned char *filedata; unsigned long filesize; int ret; CameraFile *file; struct jpeg_source_mgr xjsm; struct jpeg_decompress_struct jd; struct jpeg_error_mgr jerr; HDC dc; BITMAPINFO bmpInfo; LPBYTE bits; JSAMPROW samprow, oldsamprow; if(!libjpeg_handle) { if(!load_libjpeg()) { FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); filedata = NULL; return TWRC_FAILURE; } } gp_file_new (&file); ret = gp_camera_file_get(activeDS.camera, folder, filename, type, file, activeDS.context); if (ret < GP_OK) { FIXME("Failed to get file?\n"); gp_file_unref (file); return TWRC_FAILURE; } ret = gp_file_get_data_and_size (file, (const char**)&filedata, &filesize); if (ret < GP_OK) { FIXME("Failed to get file data?\n"); return TWRC_FAILURE; } /* FIXME: Actually we might get other types than JPEG ... But only handle JPEG for now */ if (filedata[0] != 0xff) { ERR("File %s/%s might not be JPEG, cannot decode!\n", folder, filename); } /* This is basically so we can use in-memory data for jpeg decompression. * We need to have all the functions. */ xjsm.next_input_byte = filedata; xjsm.bytes_in_buffer = filesize; xjsm.init_source = _jpeg_init_source; xjsm.fill_input_buffer = _jpeg_fill_input_buffer; xjsm.skip_input_data = _jpeg_skip_input_data; xjsm.resync_to_restart = _jpeg_resync_to_restart; xjsm.term_source = _jpeg_term_source; jd.err = pjpeg_std_error(&jerr); /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h * jpeg_create_decompress(&jd); */ pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); jd.src = &xjsm; ret=pjpeg_read_header(&jd,TRUE); jd.out_color_space = JCS_RGB; pjpeg_start_decompress(&jd); if (ret != JPEG_HEADER_OK) { ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); gp_file_unref (file); return TWRC_FAILURE; } ZeroMemory (&bmpInfo, sizeof (BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = jd.output_width; bmpInfo.bmiHeader.biHeight = -jd.output_height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = jd.output_components*8; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; *hDIB = CreateDIBSection ((dc = GetDC(hwnd)), &bmpInfo, DIB_RGB_COLORS, (LPVOID)&bits, 0, 0); if (!*hDIB) { FIXME("Failed creating DIB.\n"); gp_file_unref (file); return TWRC_FAILURE; } samprow = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components); oldsamprow = samprow; while ( jd.output_scanline<jd.output_height ) { int i, x = pjpeg_read_scanlines(&jd,&samprow,1); if (x != 1) { FIXME("failed to read current scanline?\n"); break; } /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */ for(i=0;i<jd.output_width;i++,samprow+=jd.output_components) { *(bits++) = *(samprow+2); *(bits++) = *(samprow+1); *(bits++) = *(samprow); } bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3); samprow = oldsamprow; } if (hwnd) ReleaseDC (hwnd, dc); HeapFree (GetProcessHeap(), 0, samprow); gp_file_unref (file); return TWRC_SUCCESS; }
static TW_UINT16 _get_image_and_startup_jpeg(void) { const char *folder = NULL, *filename = NULL; struct gphoto2_file *file; const unsigned char *filedata; unsigned long filesize; int ret; if (activeDS.file) /* Already loaded. */ return TWRC_SUCCESS; if(!libjpeg_handle) { if(!load_libjpeg()) { FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); filedata = NULL; return TWRC_FAILURE; } } LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) { if (strstr(file->filename,".JPG") || strstr(file->filename,".jpg")) { filename = file->filename; folder = file->folder; TRACE("downloading %s/%s\n", folder, filename); if (file->download) { file->download = FALSE; /* mark as done */ break; } } } gp_file_new (&activeDS.file); ret = gp_camera_file_get(activeDS.camera, folder, filename, GP_FILE_TYPE_NORMAL, activeDS.file, activeDS.context); if (ret < GP_OK) { FIXME("Failed to get file?\n"); activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } ret = gp_file_get_data_and_size (activeDS.file, (const char**)&filedata, &filesize); if (ret < GP_OK) { FIXME("Failed to get file data?\n"); activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } /* This is basically so we can use in-memory data for jpeg decompression. * We need to have all the functions. */ activeDS.xjsm.next_input_byte = filedata; activeDS.xjsm.bytes_in_buffer = filesize; activeDS.xjsm.init_source = _jpeg_init_source; activeDS.xjsm.fill_input_buffer = _jpeg_fill_input_buffer; activeDS.xjsm.skip_input_data = _jpeg_skip_input_data; activeDS.xjsm.resync_to_restart = _jpeg_resync_to_restart; activeDS.xjsm.term_source = _jpeg_term_source; activeDS.jd.err = pjpeg_std_error(&activeDS.jerr); /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h * jpeg_create_decompress(&jd); */ pjpeg_CreateDecompress(&activeDS.jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); activeDS.jd.src = &activeDS.xjsm; ret=pjpeg_read_header(&activeDS.jd,TRUE); activeDS.jd.out_color_space = JCS_RGB; pjpeg_start_decompress(&activeDS.jd); if (ret != JPEG_HEADER_OK) { ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); gp_file_unref (activeDS.file); activeDS.file = NULL; return TWRC_FAILURE; } return TWRC_SUCCESS; }