Esempio n. 1
0
// Virtual
// Parse PNG image information and set the appropriate
// width, height and component (channel) information.
BOOL LLImagePNG::updateData()
{
    resetLastError();

    // Check to make sure that this instance has been initialized with data
    if (!getData() || (0 == getDataSize()))
    {
        setLastError("Uninitialized instance of LLImagePNG");
        return FALSE;
    }

	// Decode the PNG data and extract sizing information
	LLPngWrapper pngWrapper;
	if (!pngWrapper.isValidPng(getData()))
	{
		setLastError("LLImagePNG data does not have a valid PNG header!");
		return FALSE;
	}

	LLPngWrapper::ImageInfo infop;
	if (! pngWrapper.readPng(getData(), NULL, &infop))
	{
		setLastError(pngWrapper.getErrorMessage());
		return FALSE;
	}

	setSize(infop.mWidth, infop.mHeight, infop.mComponents);

	return TRUE;
}
Esempio n. 2
0
// Virtual
// Encode the in memory RGB image into PNG format.
BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
{
	llassert_always(raw_image);

    resetLastError();

	// Image logical size
	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());

	// Temporary buffer to hold the encoded image. Note: the final image
	// size should be much smaller due to compression.
	U32 bufferSize = getWidth() * getHeight() * getComponents() + 1024;
    U8* tmpWriteBuffer = new U8[ bufferSize ];

	// Delegate actual encoding work to wrapper
	LLPngWrapper pngWrapper;
	if (! pngWrapper.writePng(raw_image, tmpWriteBuffer))
	{
		setLastError(pngWrapper.getErrorMessage());
		delete[] tmpWriteBuffer;
		return FALSE;
	}

	// Resize internal buffer and copy from temp
	U32 encodedSize = pngWrapper.getFinalSize();
	allocateData(encodedSize);
	memcpy(getData(), tmpWriteBuffer, encodedSize);

	delete[] tmpWriteBuffer;

	return TRUE;
}
Esempio n. 3
0
// Virtual
// Decode an in-memory PNG image into the raw RGB or RGBA format
// used within SecondLife.
BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
{
	llassert_always(raw_image);

    resetLastError();

    // Check to make sure that this instance has been initialized with data
    if (!getData() || (0 == getDataSize()))
    {
        setLastError("LLImagePNG trying to decode an image with no data!");
        return FALSE;
    }

	// Decode the PNG data into the raw image
	LLPngWrapper pngWrapper;
	if (!pngWrapper.isValidPng(getData()))
	{
		setLastError("LLImagePNG data does not have a valid PNG header!");
		return FALSE;
	}

	if (! pngWrapper.readPng(getData(), raw_image))
	{
		setLastError(pngWrapper.getErrorMessage());
		return FALSE;
	}

	return TRUE;
}
bool SimpleDataAccessObject<T>::update(T *const object)
{
    resetLastError();
    bool ok = m_objects.contains(m_metaObject.primaryKeyProperty().read(object));
    if(ok)
        emit objectUpdated(object);
    return ok;
}
bool SimpleDataAccessObject<T>::remove(T *const object)
{
    resetLastError();
    QVariant key = m_metaObject.primaryKeyProperty().read(object);
    bool ok = m_objects.contains(key);
    if(ok) {
        m_objects.remove(key);
        emit objectRemoved(object);
    }
    return ok;
}
T *SimpleDataAccessObject<T>::read(const QVariant &key) const
{
    resetLastError();
    int type = m_metaObject.primaryKeyProperty().type();
    Q_ASSERT(key.canConvert(type));

    QVariant keyVariant(key);
    keyVariant.convert(type);

    return m_objects.value(keyVariant);
}
Esempio n. 7
0
BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
{
	llassert_always(raw_image);
	
	resetLastError();

	// Check to make sure that this instance has been initialized with data
	U8* mdata = getData();
	if (!mdata || (0 == getDataSize()))
	{
		setLastError("llimagebmp trying to decode an image with no data!");
		return FALSE;
	}
	
	raw_image->resize(getWidth(), getHeight(), 3);

	U8* src = mdata + mBitmapOffset;
	U8* dst = raw_image->getData();

	BOOL success = FALSE;

	switch( mBitsPerPixel )
	{
	case 8:
		if( mColorPaletteColors >= 256 )
		{
			success = decodeColorTable8( dst, src );
		}
		break;
	
	case 16:
		success = decodeColorMask16( dst, src );
		break;
	
	case 24:
		success = decodeTruecolor24( dst, src );
		break;

	case 32:
		success = decodeColorMask32( dst, src );
		break;
	}

	if( success && mOriginAtTop )
	{
		raw_image->verticalFlip();
	}

	return success;
}
bool SimpleDataAccessObject<T>::insert(T * const object)
{
    resetLastError();
    QVariant key = m_metaObject.primaryKeyProperty().read(object);
    if(m_objects.contains(key)) {
        setLastError(QDataSuite::Error("An object with this key already exists.",
                                       QDataSuite::Error::StorageError));
        return false;
    }

    m_objects.insert(key, object);
    emit objectInserted(object);
    return true;
}
Esempio n. 9
0
BOOL LLImageJPEG::updateData()
{
	resetLastError();

	// Check to make sure that this instance has been initialized with data
	if (!getData() || (0 == getDataSize()))
	{
		setLastError("Uninitialized instance of LLImageJPEG");
		return FALSE;
	}

	////////////////////////////////////////
	// Step 1: allocate and initialize JPEG decompression object

	// This struct contains the JPEG decompression parameters and pointers to
	// working space (which is allocated as needed by the JPEG library).
	struct jpeg_decompress_struct cinfo;
	cinfo.client_data = this;

	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);
	
	// Customize with our own callbacks
	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
	
	//
	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
	//
	if(setjmp(sSetjmpBuffer))
	{
		jpeg_destroy_decompress(&cinfo);
		return FALSE;
	}
	try
	{
		// Now we can initialize the JPEG decompression object.
		jpeg_create_decompress(&cinfo);

		////////////////////////////////////////
		// Step 2: specify data source
		// (Code is modified version of jpeg_stdio_src();
		if (cinfo.src == NULL)
		{	
			cinfo.src = (struct jpeg_source_mgr *)
				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
				sizeof(struct jpeg_source_mgr));
		}
		cinfo.src->init_source	=		&LLImageJPEG::decodeInitSource;
		cinfo.src->fill_input_buffer =	&LLImageJPEG::decodeFillInputBuffer;
		cinfo.src->skip_input_data =	&LLImageJPEG::decodeSkipInputData;
		cinfo.src->resync_to_restart = jpeg_resync_to_restart; // For now, use default method, but we should be able to do better.
		cinfo.src->term_source =		&LLImageJPEG::decodeTermSource;

		cinfo.src->bytes_in_buffer =	getDataSize();
		cinfo.src->next_input_byte =	getData();
		
		////////////////////////////////////////
		// Step 3: read file parameters with jpeg_read_header()
		jpeg_read_header( &cinfo, TRUE );

		// Data set by jpeg_read_header
		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)

		/*
		// More data set by jpeg_read_header
		cinfo.num_components;
		cinfo.jpeg_color_space;	// Colorspace of image
		cinfo.saw_JFIF_marker;		// TRUE if a JFIF APP0 marker was seen
		cinfo.JFIF_major_version;	// Version information from JFIF marker
		cinfo.JFIF_minor_version;  //
		cinfo.density_unit;		// Resolution data from JFIF marker
		cinfo.X_density;
		cinfo.Y_density;
		cinfo.saw_Adobe_marker;	// TRUE if an Adobe APP14 marker was seen
		cinfo.Adobe_transform;     // Color transform code from Adobe marker
		*/
	}
	catch (int)
	{
		jpeg_destroy_decompress(&cinfo);

		return FALSE;
	}
	////////////////////////////////////////
	// Step 4: Release JPEG decompression object 
	jpeg_destroy_decompress(&cinfo);

	return TRUE;
}
Esempio n. 10
0
BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
{
	llassert_always(raw_image);
	
	resetLastError();

	switch( raw_image->getComponents() )
	{
	case 1:
	case 3:
		break;
	default:
		setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
		return FALSE;
	}

	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());

	// Allocate a temporary buffer big enough to hold the entire compressed image (and then some)
	// (Note: we make it bigger in emptyOutputBuffer() if we need to)
	delete[] mOutputBuffer;
	mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024;
	mOutputBuffer = new U8[ mOutputBufferSize ];

	const U8* raw_image_data = NULL;
	S32 row_stride = 0;

	////////////////////////////////////////
	// Step 1: allocate and initialize JPEG compression object

	// This struct contains the JPEG compression parameters and pointers to
	// working space (which is allocated as needed by the JPEG library).
	struct jpeg_compress_struct cinfo;
	cinfo.client_data = this;

	// We have to set up the error handler first, in case the initialization
	// step fails.  (Unlikely, but it could happen if you are out of memory.)
	// This routine fills in the contents of struct jerr, and returns jerr's
	// address which we place into the link field in cinfo.
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);

	// Customize with our own callbacks
	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message

	//
	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
	//
	if( setjmp(sSetjmpBuffer) ) 
	{
		// If we get here, the JPEG code has signaled an error.
		// We need to clean up the JPEG object, close the input file, and return.
		jpeg_destroy_compress(&cinfo);
		delete[] mOutputBuffer;
		mOutputBuffer = NULL;
		mOutputBufferSize = 0;
		return FALSE;
	}

	try
	{

		// Now we can initialize the JPEG compression object.
		jpeg_create_compress(&cinfo);

		////////////////////////////////////////
		// Step 2: specify data destination
		// (code is a modified form of jpeg_stdio_dest() )
		if( cinfo.dest == NULL)
		{	
			cinfo.dest = (struct jpeg_destination_mgr *)
				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
				sizeof(struct jpeg_destination_mgr));
		}
		cinfo.dest->next_output_byte =		mOutputBuffer;		// => next byte to write in buffer
		cinfo.dest->free_in_buffer =		mOutputBufferSize;	// # of byte spaces remaining in buffer
		cinfo.dest->init_destination =		&LLImageJPEG::encodeInitDestination;
		cinfo.dest->empty_output_buffer =	&LLImageJPEG::encodeEmptyOutputBuffer;
		cinfo.dest->term_destination =		&LLImageJPEG::encodeTermDestination;

		////////////////////////////////////////
		// Step 3: set parameters for compression 
		//
		// First we supply a description of the input image.
		// Four fields of the cinfo struct must be filled in:
		
		cinfo.image_width = getWidth(); 	// image width and height, in pixels 
		cinfo.image_height = getHeight();

		switch( getComponents() )
		{
		case 1:
			cinfo.input_components = 1;		// # of color components per pixel
			cinfo.in_color_space = JCS_GRAYSCALE; // colorspace of input image
			break;
		case 3:
			cinfo.input_components = 3;		// # of color components per pixel
			cinfo.in_color_space = JCS_RGB; // colorspace of input image
			break;
		default:
			setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
			return FALSE;
		}

		// Now use the library's routine to set default compression parameters.
		// (You must set at least cinfo.in_color_space before calling this,
		// since the defaults depend on the source color space.)
		jpeg_set_defaults(&cinfo);

		// Now you can set any non-default parameters you wish to.
		jpeg_set_quality(&cinfo, mEncodeQuality, TRUE );  // limit to baseline-JPEG values

		////////////////////////////////////////
		// Step 4: Start compressor 
		//
		// TRUE ensures that we will write a complete interchange-JPEG file.
		// Pass TRUE unless you are very sure of what you're doing.
   
		jpeg_start_compress(&cinfo, TRUE);

		////////////////////////////////////////
		// Step 5: while (scan lines remain to be written) 
		//            jpeg_write_scanlines(...); 

		// Here we use the library's state variable cinfo.next_scanline as the
		// loop counter, so that we don't have to keep track ourselves.
		// To keep things simple, we pass one scanline per call; you can pass
		// more if you wish, though.
   
		row_stride = getWidth() * getComponents();	// JSAMPLEs per row in image_buffer

		// NOTE: For compatibility with LLImage, we need to invert the rows.
		raw_image_data = raw_image->getData();
		
		const U8* last_row_data = raw_image_data + (getHeight()-1) * row_stride;

		JSAMPROW row_pointer[1];				// pointer to JSAMPLE row[s]
		while (cinfo.next_scanline < cinfo.image_height) 
		{
			// jpeg_write_scanlines expects an array of pointers to scanlines.
			// Here the array is only one element long, but you could pass
			// more than one scanline at a time if that's more convenient.

			//Ugly const uncast here (jpeg_write_scanlines should take a const* but doesn't)
			//row_pointer[0] = (JSAMPROW)(raw_image_data + (cinfo.next_scanline * row_stride));
			row_pointer[0] = (JSAMPROW)(last_row_data - (cinfo.next_scanline * row_stride));

			jpeg_write_scanlines(&cinfo, row_pointer, 1);
		}

		////////////////////////////////////////
		//   Step 6: Finish compression 
		jpeg_finish_compress(&cinfo);

		// After finish_compress, we can release the temp output buffer. 
		delete[] mOutputBuffer;
		mOutputBuffer = NULL;
		mOutputBufferSize = 0;

		////////////////////////////////////////
		//   Step 7: release JPEG compression object 
		jpeg_destroy_compress(&cinfo);
	}

	catch(int)
	{
		jpeg_destroy_compress(&cinfo);
		delete[] mOutputBuffer;
		mOutputBuffer = NULL;
		mOutputBufferSize = 0;
		return FALSE;
	}

	return TRUE;
}
Esempio n. 11
0
// Returns true when done, whether or not decode was successful.
BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
{
	llassert_always(raw_image);
	
	resetLastError();
	
	// Check to make sure that this instance has been initialized with data
	if (!getData() || (0 == getDataSize()))
	{
		setLastError("LLImageJPEG trying to decode an image with no data!");
		return TRUE;  // done
	}
	
	S32 row_stride = 0;
	U8* raw_image_data = NULL;

	////////////////////////////////////////
	// Step 1: allocate and initialize JPEG decompression object

	// This struct contains the JPEG decompression parameters and pointers to
	// working space (which is allocated as needed by the JPEG library).
	struct jpeg_decompress_struct cinfo;

	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);
	
	// Customize with our own callbacks
	jerr.error_exit =		&LLImageJPEG::errorExit;			// Error exit handler: does not return to caller
	jerr.emit_message =		&LLImageJPEG::errorEmitMessage;		// Conditionally emit a trace or warning message
	jerr.output_message =	&LLImageJPEG::errorOutputMessage;	// Routine that actually outputs a trace or error message
	
	//
	//try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error
	//so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao 
	//
	if(setjmp(sSetjmpBuffer))
	{
		jpeg_destroy_decompress(&cinfo);
		return TRUE; // done
	}
	try
	{
		// Now we can initialize the JPEG decompression object.
		jpeg_create_decompress(&cinfo);

		////////////////////////////////////////
		// Step 2: specify data source
		// (Code is modified version of jpeg_stdio_src();
		if (cinfo.src == NULL)
		{	
			cinfo.src = (struct jpeg_source_mgr *)
				(*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
				sizeof(struct jpeg_source_mgr));
		}
		cinfo.src->init_source	=		&LLImageJPEG::decodeInitSource;
		cinfo.src->fill_input_buffer =	&LLImageJPEG::decodeFillInputBuffer;
		cinfo.src->skip_input_data =	&LLImageJPEG::decodeSkipInputData;
		cinfo.src->resync_to_restart = jpeg_resync_to_restart; // For now, use default method, but we should be able to do better.
		cinfo.src->term_source =		&LLImageJPEG::decodeTermSource;
		cinfo.src->bytes_in_buffer =	getDataSize();
		cinfo.src->next_input_byte =	getData();
		
		////////////////////////////////////////
		// Step 3: read file parameters with jpeg_read_header()
		
		jpeg_read_header(&cinfo, TRUE);

		// We can ignore the return value from jpeg_read_header since
		//   (a) suspension is not possible with our data source, and
		//   (b) we passed TRUE to reject a tables-only JPEG file as an error.
		// See libjpeg.doc for more info.

		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)

		raw_image->resize(getWidth(), getHeight(), getComponents());
		raw_image_data = raw_image->getData();
		
		
		////////////////////////////////////////
		// Step 4: set parameters for decompression 
		cinfo.out_color_components = 3;
		cinfo.out_color_space = JCS_RGB;
   

		////////////////////////////////////////
		// Step 5: Start decompressor 
		
		jpeg_start_decompress(&cinfo);
		// We can ignore the return value since suspension is not possible
		// with our data source.
		
		// We may need to do some setup of our own at this point before reading
		// the data.  After jpeg_start_decompress() we have the correct scaled
		// output image dimensions available, as well as the output colormap
		// if we asked for color quantization.
		// In this example, we need to make an output work buffer of the right size.
    
		// JSAMPLEs per row in output buffer 
		row_stride = cinfo.output_width * cinfo.output_components;
		
		////////////////////////////////////////
		// Step 6: while (scan lines remain to be read) 
		//           jpeg_read_scanlines(...); 
		
		// Here we use the library's state variable cinfo.output_scanline as the
		// loop counter, so that we don't have to keep track ourselves.
		
		// Move pointer to last line
		raw_image_data += row_stride * (cinfo.output_height - 1);

		while (cinfo.output_scanline < cinfo.output_height)
		{
			// jpeg_read_scanlines expects an array of pointers to scanlines.
			// Here the array is only one element long, but you could ask for
			// more than one scanline at a time if that's more convenient.
			
			jpeg_read_scanlines(&cinfo, &raw_image_data, 1);
			raw_image_data -= row_stride;  // move pointer up a line
		}

		////////////////////////////////////////
		// Step 7: Finish decompression 
		jpeg_finish_decompress(&cinfo);

		////////////////////////////////////////
		// Step 8: Release JPEG decompression object 
		jpeg_destroy_decompress(&cinfo);
	}

	catch (int)
	{
		jpeg_destroy_decompress(&cinfo);
		return TRUE; // done
	}

	// Check to see whether any corrupt-data warnings occurred
	if( jerr.num_warnings != 0 )
	{
		// TODO: extract the warning to find out what went wrong.
		setLastError( "Unable to decode JPEG image.");
		return TRUE; // done
	}

	return TRUE;
}
Esempio n. 12
0
BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
{
	llassert_always(raw_image);
	
	resetLastError();

	S32 src_components = raw_image->getComponents();
	S32 dst_components =  ( src_components < 3 ) ? 1 : 3;

	if( (2 == src_components) || (4 == src_components) )
	{
		llinfos << "Dropping alpha information during BMP encoding" << llendl;
	}

	setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components);
	
	U8 magic[14];
	LLBMPHeader header;
	int header_bytes = 14+sizeof(header);
	llassert(header_bytes == 54);
	if (getComponents() == 1)
	{
		header_bytes += 1024; // Need colour LUT.
	}
	int line_bytes = getComponents() * getWidth();
	int alignment_bytes = (3 * line_bytes) % 4;
	line_bytes += alignment_bytes;
	int file_bytes = line_bytes*getHeight() + header_bytes;

	// Allocate the new buffer for the data.
	if(!allocateData(file_bytes)) //memory allocation failed
	{
		return FALSE ;
	}

	magic[0] = 'B'; magic[1] = 'M';
	magic[2] = (U8) file_bytes;
	magic[3] = (U8)(file_bytes>>8);
	magic[4] = (U8)(file_bytes>>16);
	magic[5] = (U8)(file_bytes>>24);
	magic[6] = magic[7] = magic[8] = magic[9] = 0;
	magic[10] = (U8) header_bytes;
	magic[11] = (U8)(header_bytes>>8);
	magic[12] = (U8)(header_bytes>>16);
	magic[13] = (U8)(header_bytes>>24);
	header.mSize = 40;
	header.mWidth = getWidth();
	header.mHeight = getHeight();
	header.mPlanes = 1;
	header.mBitsPerPixel = (getComponents()==1)?8:24;
	header.mCompression = 0;
	header.mAlignmentPadding = 0;
	header.mImageSize = 0;
#if LL_DARWIN
	header.mHorzPelsPerMeter = header.mVertPelsPerMeter = 2834;	// 72dpi
#else
	header.mHorzPelsPerMeter = header.mVertPelsPerMeter = 0;
#endif
	header.mNumColors = header.mNumColorsImportant = 0;

	// convert BMP header to little endian (no-op on little endian builds)
	llendianswizzleone(header.mSize);
	llendianswizzleone(header.mWidth);
	llendianswizzleone(header.mHeight);
	llendianswizzleone(header.mPlanes);
	llendianswizzleone(header.mBitsPerPixel);
	llendianswizzleone(header.mCompression);
	llendianswizzleone(header.mAlignmentPadding);
	llendianswizzleone(header.mImageSize);
	llendianswizzleone(header.mHorzPelsPerMeter);
	llendianswizzleone(header.mVertPelsPerMeter);
	llendianswizzleone(header.mNumColors);
	llendianswizzleone(header.mNumColorsImportant);

	U8* mdata = getData();
	
	// Output magic, then header, then the palette table, then the data.
	U32 cur_pos = 0;
	memcpy(mdata, magic, 14);
	cur_pos += 14;
	memcpy(mdata+cur_pos, &header, 40);	/* Flawfinder: ignore */
	cur_pos += 40;
	if (getComponents() == 1)
	{
		S32 n;
		for (n=0; n < 256; n++)
		{
			mdata[cur_pos++] = (U8)n;
			mdata[cur_pos++] = (U8)n;
			mdata[cur_pos++] = (U8)n;
			mdata[cur_pos++] = 0;
		}
	}
	
	// Need to iterate through, because we need to flip the RGB.
	const U8* src = raw_image->getData();
	U8* dst = mdata + cur_pos;

	for( S32 row = 0; row < getHeight(); row++ )
	{
		for( S32 col = 0; col < getWidth(); col++ )
		{
			switch( src_components )
			{
			case 1:
				*dst++ = *src++;
				break;
			case 2:
				{
					U32 lum = src[0];
					U32 alpha = src[1];
					*dst++ = (U8)(lum * alpha / 255);
					src += 2;
					break;
				}
			case 3:
			case 4:
				dst[0] = src[2];
				dst[1] = src[1];
				dst[2] = src[0];
				src += src_components;
				dst += 3;
				break;
			}

		}
		for( S32 i = 0; i < alignment_bytes; i++ )
		{
			*dst++ = 0;
		}
	}

	return TRUE;
}
Esempio n. 13
0
BOOL LLImageBMP::updateData()
{
	resetLastError();

	// Check to make sure that this instance has been initialized with data
	U8* mdata = getData();
	if (!mdata || (0 == getDataSize()))
	{
		setLastError("Uninitialized instance of LLImageBMP");
		return FALSE;
	}

	// Read the bitmap headers in order to get all the useful info
	// about this image

	////////////////////////////////////////////////////////////////////
	// Part 1: "File Header"
	// 14 bytes consisting of
	// 2 bytes: either BM or BA
	// 4 bytes: file size in bytes
	// 4 bytes: reserved (always 0)
	// 4 bytes: bitmap offset (starting position of image data in bytes)
	const S32 FILE_HEADER_SIZE = 14;
	if ((mdata[0] != 'B') || (mdata[1] != 'M'))
    {
		if ((mdata[0] != 'B') || (mdata[1] != 'A'))
		{
			setLastError("OS/2 bitmap array BMP files are not supported");
			return FALSE;
		}
		else
		{
			setLastError("Does not appear to be a bitmap file");
			return FALSE;
		}
	}

	mBitmapOffset = mdata[13];
	mBitmapOffset <<= 8; mBitmapOffset += mdata[12];
	mBitmapOffset <<= 8; mBitmapOffset += mdata[11];
	mBitmapOffset <<= 8; mBitmapOffset += mdata[10];


	////////////////////////////////////////////////////////////////////
	// Part 2: "Bitmap Header"
	const S32 BITMAP_HEADER_SIZE = 40;
	LLBMPHeader header;
	llassert( sizeof( header ) == BITMAP_HEADER_SIZE );

	memcpy(	/* Flawfinder: ignore */
		(void*)&header,
		mdata + FILE_HEADER_SIZE,
		BITMAP_HEADER_SIZE);

	// convert BMP header from little endian (no-op on little endian builds)
	llendianswizzleone(header.mSize);
	llendianswizzleone(header.mWidth);
	llendianswizzleone(header.mHeight);
	llendianswizzleone(header.mPlanes);
	llendianswizzleone(header.mBitsPerPixel);
	llendianswizzleone(header.mCompression);
	llendianswizzleone(header.mAlignmentPadding);
	llendianswizzleone(header.mImageSize);
	llendianswizzleone(header.mHorzPelsPerMeter);
	llendianswizzleone(header.mVertPelsPerMeter);
	llendianswizzleone(header.mNumColors);
	llendianswizzleone(header.mNumColorsImportant);

	BOOL windows_nt_version = FALSE;
	BOOL windows_95_version = FALSE;
	if( 12 == header.mSize )
	{
		setLastError("Windows 2.x and OS/2 1.x BMP files are not supported");
		return FALSE;
	}
	else
	if( 40 == header.mSize )
	{
		if( 3 == header.mCompression )
		{
			// Windows NT
			windows_nt_version = TRUE;
		}
		else
		{
			// Windows 3.x
		}
	}
	else
	if( 12 <= header.mSize && 64 <= header.mSize )
	{
		setLastError("OS/2 2.x BMP files are not supported");
		return FALSE;
	}
	else
	if( 108 == header.mSize )
	{
		// BITMAPV4HEADER
		windows_95_version = TRUE;
	}
	else
	if( 108 < header.mSize )
	{
		// BITMAPV5HEADER or greater
		// Should work as long at Microsoft maintained backwards compatibility (which they did in V4 and V5)
		windows_95_version = TRUE;
	}

	S32 width = header.mWidth;
	S32 height = header.mHeight;
	if (height < 0)
	{
		mOriginAtTop = TRUE;
		height = -height;
	}
	else
	{
		mOriginAtTop = FALSE;
	}

	mBitsPerPixel = header.mBitsPerPixel;
	S32 components;
	switch( mBitsPerPixel )
	{
	case 8:
		components = 1;
		break;
	case 24:
	case 32:
		components = 3;
		break;
	case 1:
	case 4:
	case 16: // Started work on 16, but doesn't work yet
		// These are legal, but we don't support them yet.
		setLastError("Unsupported bit depth");
		return FALSE;
	default:
		setLastError("Unrecognized bit depth");
		return FALSE;
	}

	setSize(width, height, components);
	
	switch( header.mCompression )
	{
	case 0:
		// Uncompressed
		break;

	case 1:
		setLastError("8 bit RLE compression not supported.");
		return FALSE;

	case 2: 
		setLastError("4 bit RLE compression not supported.");
		return FALSE;

	case 3:
		// Windows NT or Windows 95
		break;

	default:
		setLastError("Unsupported compression format.");
		return FALSE;
	}

	////////////////////////////////////////////////////////////////////
	// Part 3: Bitfield Masks and other color data
	S32 extension_size = 0;
	if( windows_nt_version )
	{
		if( (16 != header.mBitsPerPixel) && (32 != header.mBitsPerPixel) )
		{
			setLastError("Bitfield encoding requires 16 or 32 bits per pixel.");
			return FALSE;
		}

		if( 0 != header.mNumColors )
		{
			setLastError("Bitfield encoding is not compatible with a color table.");
			return FALSE;
		}

		
		extension_size = 4 * 3;
		memcpy( mBitfieldMask, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, extension_size);	/* Flawfinder: ignore */
	}
	else
	if( windows_95_version )
	{
		Win95BmpHeaderExtension win_95_extension;
		extension_size = sizeof( win_95_extension );

		llassert( sizeof( win_95_extension ) + BITMAP_HEADER_SIZE == 108 );
		memcpy( &win_95_extension, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, sizeof( win_95_extension ) );	/* Flawfinder: ignore */

		if( 3 == header.mCompression )
		{
			memcpy( mBitfieldMask, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, 4 * 4);	/* Flawfinder: ignore */
		}

		// Color correction ignored for now
	}
	

	////////////////////////////////////////////////////////////////////
	// Part 4: Color Palette (optional)
	// Note: There's no color palette if there are 16 or more bits per pixel
	S32 color_palette_size = 0;
	mColorPaletteColors = 0;
	if( header.mBitsPerPixel < 16 )
	{
		if( 0 == header.mNumColors )
		{
			mColorPaletteColors = (1 << header.mBitsPerPixel);
		}
		else
		{
			mColorPaletteColors = header.mNumColors;
		}
	}
	color_palette_size = mColorPaletteColors * 4;

	if( 0 != mColorPaletteColors )
	{
		mColorPalette = new U8[color_palette_size];
		if (!mColorPalette)
		{
			llwarns << "Out of memory in LLImageBMP::updateData()" << llendl;
			return FALSE;
		}
		memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size );	/* Flawfinder: ignore */
	}

	return TRUE;
}
Esempio n. 14
0
BOOL LLImageTGA::updateData()
{
	resetLastError();

	// Check to make sure that this instance has been initialized with data
	if (!getData() || (0 == getDataSize()))
	{
		setLastError("LLImageTGA uninitialized");
		return FALSE;
	}
	
	// Pull image information from the header...
	U8	flags;
	U8	junk[256];

	/****************************************************************************
	**
	**	For more information about the original Truevision TGA(tm) file format,
	**	or for additional information about the new extensions to the
	**	Truevision TGA file, refer to the "Truevision TGA File Format
	**	Specification Version 2.0" available from Truevision or your
	**	Truevision dealer.
	**
	**  FILE STRUCTURE FOR THE ORIGINAL TRUEVISION TGA FILE				
	**	  FIELD 1 :	NUMBER OF CHARACTERS IN ID FIELD (1 BYTES)	
	**	  FIELD 2 :	COLOR MAP TYPE (1 BYTES)			
	**	  FIELD 3 :	IMAGE TYPE CODE (1 BYTES)			
	**					= 0	NO IMAGE DATA INCLUDED		
	**					= 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
	**					= 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
	**					= 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
	**					= 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
	**					= 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
	**					= 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
	**	  FIELD 4 :	COLOR MAP SPECIFICATION	(5 BYTES)		
	**				4.1 : COLOR MAP ORIGIN (2 BYTES)	
	**				4.2 : COLOR MAP LENGTH (2 BYTES)	
	**				4.3 : COLOR MAP ENTRY SIZE (2 BYTES)	
	**	  FIELD 5 :	IMAGE SPECIFICATION (10 BYTES)			
	**				5.1 : X-ORIGIN OF IMAGE (2 BYTES)	
	**				5.2 : Y-ORIGIN OF IMAGE (2 BYTES)	
	**				5.3 : WIDTH OF IMAGE (2 BYTES)		
	**				5.4 : HEIGHT OF IMAGE (2 BYTES)		
	**				5.5 : IMAGE PIXEL SIZE (1 BYTE)		
	**				5.6 : IMAGE DESCRIPTOR BYTE (1 BYTE) 	
	**	  FIELD 6 :	IMAGE ID FIELD (LENGTH SPECIFIED BY FIELD 1)	
	**	  FIELD 7 :	COLOR MAP DATA (BIT WIDTH SPECIFIED BY FIELD 4.3 AND
	**				NUMBER OF COLOR MAP ENTRIES SPECIFIED IN FIELD 4.2)
	**	  FIELD 8 :	IMAGE DATA FIELD (WIDTH AND HEIGHT SPECIFIED IN
	**				FIELD 5.3 AND 5.4)				
	****************************************************************************/

	mDataOffset = 0;
	mIDLength = *(getData()+mDataOffset++);
	mColorMapType = *(getData()+mDataOffset++);
	mImageType = *(getData()+mDataOffset++);
	mColorMapIndexLo = *(getData()+mDataOffset++);
	mColorMapIndexHi = *(getData()+mDataOffset++);
	mColorMapLengthLo = *(getData()+mDataOffset++);
	mColorMapLengthHi = *(getData()+mDataOffset++);
	mColorMapDepth = *(getData()+mDataOffset++);
	mXOffsetLo = *(getData()+mDataOffset++);
	mXOffsetHi = *(getData()+mDataOffset++);
	mYOffsetLo = *(getData()+mDataOffset++);
	mYOffsetHi = *(getData()+mDataOffset++);
	mWidthLo = *(getData()+mDataOffset++);
	mWidthHi = *(getData()+mDataOffset++);
	mHeightLo = *(getData()+mDataOffset++);
	mHeightHi = *(getData()+mDataOffset++);
	mPixelSize = *(getData()+mDataOffset++);
	flags = *(getData()+mDataOffset++);
	mAttributeBits = flags & 0xf;
	mOriginRightBit = (flags & 0x10) >> 4;
	mOriginTopBit = (flags & 0x20) >> 5;
	mInterleave = (flags & 0xc0) >> 6;

	switch( mImageType )
	{
	case 0:
		// No image data included in file
		setLastError("Unable to load file.  TGA file contains no image data.");
		return FALSE;
	case 1:
		// Colormapped uncompressed
		if( 8 != mPixelSize )
		{
			setLastError("Unable to load file.  Colormapped images must have 8 bits per pixel.");
			return FALSE;
		}
		break;
	case 2:
		// Truecolor uncompressed
		break;
	case 3:
		// Monochrome uncompressed
		if( 8 != mPixelSize )
		{
			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
			return FALSE;
		}
		break;
	case 9:
		// Colormapped, RLE
		break;
	case 10:
		// Truecolor, RLE
		break;
	case 11:
		// Monochrome, RLE
		if( 8 != mPixelSize )
		{
			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
			return FALSE;
		}
		break;
	default:
		setLastError("Unable to load file.  Unrecoginzed TGA image type.");
		return FALSE;
	}

	// discard the ID field, if any
	if (mIDLength)
	{
		memcpy(junk, getData()+mDataOffset, mIDLength);	/* Flawfinder: ignore */
		mDataOffset += mIDLength;
	}
	
	// check to see if there's a colormap since even rgb files can have them
	S32 color_map_bytes = 0;
	if( (1 == mColorMapType) && (mColorMapDepth > 0) )
	{
		mColorMapStart = (S32(mColorMapIndexHi) << 8) + mColorMapIndexLo;
		mColorMapLength = (S32(mColorMapLengthHi) << 8) + mColorMapLengthLo;
		
		if( mColorMapDepth > 24 )
		{
			mColorMapBytesPerEntry = 4;
		}
		else
		if( mColorMapDepth > 16 )
		{
			mColorMapBytesPerEntry = 3;
		}
		else
		if( mColorMapDepth > 8 )
		{
			mColorMapBytesPerEntry = 2;
		}
		else
		{
			mColorMapBytesPerEntry = 1;
		}
		color_map_bytes = mColorMapLength * mColorMapBytesPerEntry;

		// Note: although it's legal for TGA files to have color maps and not use them
		// (some programs actually do this and use the color map for other ends), we'll
		// only allocate memory for one if _we_ intend to use it.
		if ( (1 == mImageType) || (9 == mImageType)  )
		{
			mColorMap = new U8[ color_map_bytes ];  
			if (!mColorMap)
			{
				LL_ERRS() << "Out of Memory in BOOL LLImageTGA::updateData()" << LL_ENDL;
				return FALSE;
			}
			memcpy( mColorMap, getData() + mDataOffset, color_map_bytes );	/* Flawfinder: ignore */
		}

		mDataOffset += color_map_bytes;
	}

	// heights are read as bytes to prevent endian problems
	S32 height = (S32(mHeightHi) << 8) + mHeightLo;
	S32 width = (S32(mWidthHi) << 8) + mWidthLo;

	// make sure that it's a pixel format that we understand
	S32 bits_per_pixel;
	if( mColorMap )
	{
		bits_per_pixel = mColorMapDepth;
	}
	else
	{
		bits_per_pixel = mPixelSize;
	}

	S32 components;
	switch(bits_per_pixel)
	{
	case 24:
		components = 3;
		break;
	case 32:
		components = 4;
//		Don't enforce this.  ACDSee doesn't bother to set the attributes bits correctly. Arrgh!
//		if( mAttributeBits != 8 )
//		{
//			setLastError("Unable to load file. 32 bit TGA image does not have 8 bits of alpha.");
//			return FALSE;
//		}
		mAttributeBits = 8;
		break;
	case 15:
	case 16:
		components = 3;
		mIs15Bit = TRUE;  // 16th bit is used for Targa hardware interupts and is ignored.
		break;
	case 8:
		components = 1;
		break;
	default:
		setLastError("Unable to load file. Unknown pixel size.");
		return FALSE;
	}
	setSize(width, height, components);
	
	return TRUE;
}
QList<QVariant> SimpleDataAccessObject<T>::allKeys() const
{
    resetLastError();
    return m_objects.keys();
}
QList<T *> SimpleDataAccessObject<T>::readAll() const
{
    resetLastError();
    return m_objects.values();
}
T *SimpleDataAccessObject<T>::create() const
{
    resetLastError();
    return new T;
}