// 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; }
// 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; }
// 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); }
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; }
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; }
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; }
// 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; }
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; }
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; }
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; }