void CL_JPEGProvider_Generic::perform_lock()
{
	if (locked++) return;

	struct jpeg_error_mgr jerr;	
	struct jpeg_decompress_struct cinfo;
	//	FILE * infile;		
	JSAMPARRAY buffer;	
	int row_stride;		
	
	input_source = input_provider->open_source(filename);

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
	jpeg_InputSource_src(&cinfo, this);
	jpeg_read_header(&cinfo, TRUE);
	jpeg_start_decompress(&cinfo);

	row_stride = cinfo.output_width * cinfo.output_components;

	width = cinfo.output_width;
	height = cinfo.output_height;
	pitch = width * 3;

	// FIXME: Where is the allocated memory freed?
	buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 32);

	image = new unsigned char[get_pitch() * cinfo.output_height];

	// RGB Image
	if (cinfo.output_components == 3)
	{
		while (cinfo.output_scanline < cinfo.output_height) 
		{
			jpeg_read_scanlines(&cinfo, buffer, 1);
		
			for(unsigned int i=0; i < get_pitch(); i += 3)
			{
				image[pitch * (cinfo.output_scanline - 1) + i + 0] = buffer[0][i + 2];
				image[pitch * (cinfo.output_scanline - 1) + i + 1] = buffer[0][i + 1];
				image[pitch * (cinfo.output_scanline - 1) + i + 2] = buffer[0][i + 0];
			}
		}
	}
	// Greyscale Image
	else if (cinfo.output_components == 1)
	{
		while (cinfo.output_scanline < cinfo.output_height) 
		{
			jpeg_read_scanlines(&cinfo, buffer, 1);
			
			for(int i=0; i < width; i += 1)
			{
				image[pitch * (cinfo.output_scanline - 1) + 3*i + 0] = buffer[0][i];
				image[pitch * (cinfo.output_scanline - 1) + 3*i + 1] = buffer[0][i];
				image[pitch * (cinfo.output_scanline - 1) + 3*i + 2] = buffer[0][i];
			}			
		}
	}
	else
	{
//		std::cout << "CL_JPEGProvider: Unsupported color completion: " << cinfo.output_components << std::endl;
		cl_assert(false);
	}
	
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	delete input_source;
	input_source = 0;
}

