Example #1
0
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return 0;

    RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
        return 0;
    
    IntRect imageRect = buffer->rect();
    unsigned char* bytes = (unsigned char*)buffer->bytes().data();
    long colorSize = buffer->bytes().size();
    
    typedef wxPixelData<wxBitmap, wxAlphaPixelFormat> PixelData;

    int width = size().width();
    int height = size().height();

    wxBitmap* bmp = new wxBitmap(width, height, 32);
    PixelData data(*bmp);
    
    int rowCounter = 0;
    long pixelCounter = 0;
    
    PixelData::Iterator p(data);
    
    PixelData::Iterator rowStart = p; 
    
    // NB: It appears that the data is in BGRA format instead of RGBA format.
    // This code works properly on both ppc and intel, meaning the issue is
    // likely not an issue of byte order getting mixed up on different archs. 
    for (long i = 0; i < buffer->bytes().size()*4; i+=4) {
        p.Red() = bytes[i+2];
        p.Green() = bytes[i+1];
        p.Blue() = bytes[i+0];
        p.Alpha() = bytes[i+3];
        
        p++;

        pixelCounter++;
        if ( (pixelCounter % width ) == 0 ) {
            rowCounter++;
            p = rowStart;
            p.MoveTo(data, 0, rowCounter);
        }

    }

    bmp->UseAlpha();
    ASSERT(bmp->IsOk());
    return bmp;
}
Example #2
0
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!initialized())
        return 0;

    if (!m_decoder)
        return 0;

    RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
        return 0;

    // Cairo does not like zero height images.
    // If we have a zero height image, just pretend we don't have enough data yet.
    if (!buffer->height())
        return 0;
    /* <lab126> */
    struct timespec startTime;
    KINDLE_BEGIN(Kindle_Debug_Perf)
    clock_gettime(CLOCK_MONOTONIC, &startTime);
    KINDLE_END()

    if (m_imageDitherType == USE_SIMPLE_ALGORITHM) {
        int imageWidth = size().width();
        int imageHeight = buffer->height();
        if(!dither_inited)
            for(int i=0; i<3333; i++)
                dither_buffer[i]=rand()%17;
        for (int n = 0; n < imageHeight; n++)
        {
            for (int m = 0; m < imageWidth; m++)
            {
                int rgb=buffer->bytes().data()[ (n*imageWidth) + m ];
                int r = (rgb >> 16) & 0xff;
                int g = (rgb >> 8) & 0xff;
                int b = rgb & 0xff;
                int gray = (r == g && g == b) ?  r : ((77 * r + 150 * g + 29 * b) >> 8);
                dither_index=(dither_index+1)%3333;
                int ngray=gray+dither_buffer[dither_index];
                ngray-=ngray%17;
                if(ngray>0xff) ngray=0xff;
                buffer->bytes().data()[ (n*imageWidth) + m ] =   (rgb&STRIP_ALPHA)|(ngray<<16)|(ngray<<8)|ngray;
            }
        }
    }
Example #3
0
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return 0;

    RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
        return 0;
        
    DEBUG( "ImageSource::createFrameAtIndex() %i %i %i\n",
    	size().width(), buffer->height(), buffer->bytes().size() );
    
    os::Bitmap* pcBitmap = new os::Bitmap( size().width(), buffer->height(), os::CS_RGBA32 );
    memcpy( pcBitmap->LockRaster(), reinterpret_cast<unsigned char*>(buffer->bytes().data()),
    			 ( buffer->height() * size().width() ) * 4  );
	pcBitmap->UnlockRaster();    			 
    return( pcBitmap );
}
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!m_decoder)
        return 0;

    RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
        return 0;

    return cairo_image_surface_create_for_data((unsigned char*)buffer->bytes().data(),
                                               CAIRO_FORMAT_ARGB32,
                                               size().width(),
                                               buffer->height(),
                                               size().width()*4);
}
Example #5
0
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
    if (!initialized())
        return 0;

    if (!m_decoder)
        return 0;

    RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
    if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
        return 0;

    // Cairo does not like zero height images.
    // If we have a zero height image, just pretend we don't have enough data yet.
    if (!buffer->height())
        return 0;

    return cairo_image_surface_create_for_data((unsigned char*)buffer->bytes().data(),
                                               CAIRO_FORMAT_ARGB32,
                                               size().width(),
                                               buffer->height(),
                                               size().width()*4);
}
Example #6
0
void GIFImageDecoder::initFrameBuffer(RGBA32Buffer& buffer, 
                                      RGBA32Buffer* previousBuffer,
                                      bool compositeWithPreviousFrame)
{
    // Initialize the frame rect in our buffer.
    IntRect frameRect(m_reader->frameXOffset(), m_reader->frameYOffset(),
                      m_reader->frameWidth(), m_reader->frameHeight());
    buffer.setRect(frameRect);

    bool isSubRect = (frameRect.x() > 0 || frameRect.y() > 0 ||
                      frameRect.width() < m_size.width() ||
                      frameRect.height() < m_size.height());
    
    // Let's resize our buffer now to the correct width/height and then
    // initialize portions of it if needed.
    RGBA32Array& bytes = buffer.bytes();
        
    // If the disposal method of the previous frame said to stick around, then we need     
    // to copy that frame into our frame.  We also dont want to have any impact on
    // anything outside our frame's rect, so if we don't overlay the entire image,
    // then also composite with the previous frame.
    if (previousBuffer && (compositeWithPreviousFrame || isSubRect)) {
        bytes = previousBuffer->bytes();
        buffer.ensureHeight(m_size.height());
        buffer.setHasAlpha(previousBuffer->hasAlpha());
    }
    else // Resize to the width and height of the image.
        bytes.resize(m_size.width() * m_size.height());

    if (isSubRect) {
        // We need to go ahead and initialize the first frame to make sure
        // that areas outside the subrect start off transparent.
        if (!previousBuffer) {
            bytes.fill(0);
            buffer.setHasAlpha(true);
        } else if (!compositeWithPreviousFrame) {
            // Now this is an interesting case.  In the case where we fill 
            // the entire image, we effectively do a full clear of the image (and thus
            // don't have to initialize anything in our buffer).
            // 
            // However in the case where we only fill a piece of the image, two problems occur:
            // (1) We need to wipe out the area occupied by the previous frame, which
            // could also have been a subrect.
            // (2) Anything outside the previous frame's rect *and* outside our current
            // frame's rect should be left alone.
            // We have handled (2) by just initializing our buffer from the previous frame.
            // Our subrect will correctly overwrite the previous frame's contents as we
            // decode rows.  However that still leaves the problem of having to wipe out
            // the area occupied by the previous frame that does not overlap with
            // the new frame.
            if (previousBuffer->rect() != frameRect) {
                // We have to clear out the entire previous subframe.
                bool sawAlpha = buffer.hasAlpha();
                IntRect prevRect = previousBuffer->rect();
                unsigned end = prevRect.y() + prevRect.height();
                unsigned* src;
                for (unsigned i = prevRect.y(); i < end; i++) {
                    unsigned* curr = buffer.bytes().data() + (i * m_size.width() + prevRect.x());
                    unsigned* end = curr + prevRect.width();
                    while (curr != end) {
                        if (!sawAlpha) {
                            sawAlpha = true;
                            buffer.setHasAlpha(true);
                        }
                        RGBA32Buffer::setRGBA(*curr++, 0, 0, 0, 0);
                    }
                }
            }
        }
    }

    // Update our status to be partially complete.
    buffer.setStatus(RGBA32Buffer::FramePartial);
}