Exemplo n.º 1
0
Image* PVRTCDecoder::Decode(DataStream* ds) {
    PVRTexHeader header;
    if (!ds) return 0;
    if ( ds->Read((Byte*)&header, sizeof(header))!=sizeof(header) )
        return 0;
    if ( header.pvrTag[0] != gPVRTexIdentifier[0] ||
            header.pvrTag[1] != gPVRTexIdentifier[1] ||
            header.pvrTag[2] != gPVRTexIdentifier[2] ||
            header.pvrTag[3] != gPVRTexIdentifier[3] )
        return 0;
    /// @todo swap bytes ordering
    UInt32 formatFlags = SwapLittleToHost(header.flags) & PVR_TEXTURE_FLAG_TYPE_MASK;
    if ( formatFlags != kPVRTextureFlagTypePVRTC_2 &&
            formatFlags != kPVRTextureFlagTypePVRTC_4 ) {
        return 0;
    }
    //bool haveAlpha = SwapLittleToHost(header.bitmaskAlpha);
    UInt32 width = SwapLittleToHost(header.width);
    UInt32 height = SwapLittleToHost(header.height);
    UInt32 dataLength = SwapLittleToHost(header.dataLength);

    UInt32 blockSize = 0;
    UInt32 widthBlocks = 0;
    UInt32 heightBlocks = 0;
    UInt32 bpp = 0;
    ImageFormat format;
    if (formatFlags == kPVRTextureFlagTypePVRTC_4)
    {
        blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
        widthBlocks = width / 4;
        heightBlocks = height / 4;
        bpp = 4;
        format = IMAGE_FORMAT_PVRTC_4;
    }
    else
    {
        blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
        widthBlocks = width / 8;
        heightBlocks = height / 4;
        bpp = 2;
        format = IMAGE_FORMAT_PVRTC_2;
    }

    // Clamp to minimum number of blocks
    if (widthBlocks < 2)
        widthBlocks = 2;
    if (heightBlocks < 2)
        heightBlocks = 2;

    UInt32 dataSize = widthBlocks * heightBlocks * ((blockSize  * bpp) / 8);
    if ( dataSize < dataLength ) return 0;
    DataImpl* buffer = new DataImpl( dataSize );
    if ( ds->Read(buffer->GetDataPtr(), dataSize )!=dataSize ) {
        buffer->Release();
        return 0;
    }
    return new ImageImpl(width,height,format,buffer);
}
Exemplo n.º 2
0
	bool GHL_CALL ImageImpl::Convert(ImageFormat fmt) {
		if (fmt==m_fmt) return true;
		if (!m_data) return false;
		const Byte* original = m_data->GetData();
		if (fmt==IMAGE_FORMAT_RGB)
		{
			size_t len = m_width*m_height;
			DataImpl* buffer = new DataImpl( len * 3 );
			Byte* data = buffer->GetDataPtr();
			if (m_fmt==IMAGE_FORMAT_RGBA) {
				for (size_t i=0;i<len;i++) {
					data[i*3+0]=original[i*4+0];
					data[i*3+1]=original[i*4+1];
					data[i*3+2]=original[i*4+2];
				}
			} else if (m_fmt==IMAGE_FORMAT_GRAY)
			{
				for (size_t i=0;i<len;i++) {
					data[i*3+0]=original[i];
					data[i*3+1]=original[i];
					data[i*3+2]=original[i];
				}
			}
			m_data->Release();
			m_data = buffer;
		}
		else if (fmt==IMAGE_FORMAT_RGBA)
		{
			size_t len = m_width*m_height;
			DataImpl* buffer = new DataImpl( len * 4 );
			Byte* data = buffer->GetDataPtr();
			if (m_fmt==IMAGE_FORMAT_RGB) {
				for (size_t i=0;i<len;i++) {
					data[i*4+0]=original[i*3+0];
					data[i*4+1]=original[i*3+1];
					data[i*4+2]=original[i*3+2];
					data[i*4+3]=0xff;
				}
			} else if (m_fmt==IMAGE_FORMAT_GRAY) {
				for (size_t i=0;i<len;i++) {
					data[i*4+0]=original[i];
					data[i*4+1]=original[i];
					data[i*4+2]=original[i];
					data[i*4+3]=0xff;
				}
			}
			m_data->Release();
			m_data = buffer;
		} else {
			return false;
		}
        m_fmt = fmt;
		return true;
	}
Exemplo n.º 3
0
	Image* GHL_CALL ImageImpl::SubImage(UInt32 x,UInt32 y,UInt32 w,UInt32 h) const {
		if (!m_data) return 0;
		if (x>m_width) return 0;
		if (y>m_height) return 0;
		if (w>m_width) return 0;
		if (h>m_height) return 0;
		if ((x+w)>m_width) return 0;
		if ((y+h)>m_height) return 0;
		DataImpl* res = new DataImpl( w * h * GetBpp() );
		Byte* data = m_data->GetDataPtr();
		for (UInt32 _y = 0; _y<h;_y++) {
			const Byte* src = data + (_y+y)*m_width*GetBpp();
			src+=x*GetBpp();
			Byte* dst = res->GetDataPtr()+_y*w*GetBpp();
			::memcpy(dst,src,w*GetBpp());
		}
		return new ImageImpl( w, h, GetFormat(), res );
	}
Exemplo n.º 4
0
    Image* JpegDecoder::Decode(DataStream* file)
    {
        if (!file) return 0;
        ImageImpl* img = 0;
        
        size_t file_size = 0;
        file->Seek(0,F_SEEK_END);
        file_size = file->Tell();
        file->Seek(0,F_SEEK_BEGIN);
        
        Byte **rowPtr=0;
        Byte* input = new Byte[file_size];
        file->Read(input, UInt32(file_size));
        
        
        // allocate and initialize JPEG decompression object
        struct jpeg_decompress_struct cinfo;
        struct ghl_jpeg_error_mgr jerr;
        
        //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.
        
        cinfo.err = jpeg_std_error(&jerr.pub);
        cinfo.err->error_exit = ghl_jpeg_error_exit;
        cinfo.err->output_message = ghl_jpeg_output_message;
        
        // compatibility fudge:
        // we need to use setjmp/longjmp for error handling as gcc-linux
        // crashes when throwing within external c code
        if (setjmp(jerr.setjmp_buffer))
        {
            // If we get here, the JPEG code has signaled an error.
            // We need to clean up the JPEG object and return.
            
            jpeg_destroy_decompress(&cinfo);
            
            delete [] input;
            // if the row pointer was created, we delete it.
            if (rowPtr)
                delete [] rowPtr;
            delete img;
            // return null pointer
            return 0;
        }
        
        // Now we can initialize the JPEG decompression object.
        jpeg_create_decompress(&cinfo);
        
        // specify data source
        jpeg_source_mgr jsrc;
        
        // Set up data pointer
        jsrc.bytes_in_buffer = file_size;
        jsrc.next_input_byte = (JOCTET*)input;
        cinfo.src = &jsrc;
        
        jsrc.init_source = ghl_jpeg_init_source;
        jsrc.fill_input_buffer = ghl_jpeg_fill_input_buffer;
        jsrc.skip_input_data = ghl_jpeg_skip_input_data;
        jsrc.resync_to_restart = jpeg_resync_to_restart;
        jsrc.term_source = ghl_jpeg_term_source;
        
        // Decodes JPG input from whatever source
        // Does everything AFTER jpeg_create_decompress
        // and BEFORE jpeg_destroy_decompress
        // Caller is responsible for arranging these + setting up cinfo
        
        // read file parameters with jpeg_read_header()
        jpeg_read_header(&cinfo, TRUE);
        
        cinfo.out_color_space=JCS_RGB;
        cinfo.out_color_components=3;
        cinfo.do_fancy_upsampling=FALSE;
        
        // Start decompressor
        jpeg_start_decompress(&cinfo);
        
        
        // Get image data
        UInt32 rowspan = cinfo.image_width * cinfo.out_color_components;
        UInt32 width = cinfo.image_width;
        UInt32 height = cinfo.image_height;
        DataImpl* data = new DataImpl(width*height*3);
        img = new ImageImpl(width,height,IMAGE_FORMAT_RGB,data);
        Byte* output = data->GetDataPtr();
        
		// 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.
        // Create array of row pointers for lib
        rowPtr = new Byte* [height];
        
        for( size_t i = 0; i < height; i++ )
            rowPtr[i] = &output[ i * rowspan ];
        
        UInt32 rowsRead = 0;
        
        while( cinfo.output_scanline < cinfo.output_height )
            rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead );
        
        delete [] rowPtr;
        // Finish decompression
        
        jpeg_finish_decompress(&cinfo);
        
        // Release JPEG decompression object
        // This is an important step since it will release a good deal of memory.
        jpeg_destroy_decompress(&cinfo);
        
        delete [] input;
        return img;
    }