示例#1
0
bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, unsigned repeatCount, bool writeTransparentPixels)
{
    const GIFFrameReader* frameReader = m_reader->frame_reader;
    // The pixel data and coordinates supplied to us are relative to the frame's
    // origin within the entire image size, i.e.
    // (frameReader->x_offset, frameReader->y_offset).  There is no guarantee
    // that (rowEnd - rowBuffer) == (size().width() - frameReader->x_offset), so
    // we must ensure we don't run off the end of either the source data or the
    // row's X-coordinates.
    int xBegin = upperBoundScaledX(frameReader->x_offset);
    int yBegin = upperBoundScaledY(frameReader->y_offset + rowNumber);
    int xEnd = lowerBoundScaledX(std::min(xBegin + static_cast<int>(rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1;
    int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1;
    if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
        return true;

    // Get the colormap.
    const unsigned char* colorMap;
    unsigned colorMapSize;
    if (frameReader->is_local_colormap_defined) {
        colorMap = frameReader->local_colormap;
        colorMapSize = (unsigned)frameReader->local_colormap_size;
    } else {
        colorMap = m_reader->global_colormap;
        colorMapSize = m_reader->global_colormap_size;
    }
    if (!colorMap)
        return true;

    // Initialize the frame if necessary.
    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
        return false;
    
    // Write one row's worth of data into the frame.  
    for (int x = xBegin; x < xEnd; ++x) {
        const unsigned char sourceValue = *(rowBuffer + (m_scaled ? m_scaledColumns[x] : x) - frameReader->x_offset);
        if ((!frameReader->is_transparent || (sourceValue != frameReader->tpixel)) && (sourceValue < colorMapSize)) {
            const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
            buffer.setRGBA(x, yBegin, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
        } else {
            m_currentBufferSawAlpha = true;
            // We may or may not need to write transparent pixels to the buffer.
            // If we're compositing against a previous image, it's wrong, and if
            // we're writing atop a cleared, fully transparent buffer, it's
            // unnecessary; but if we're decoding an interlaced gif and
            // displaying it "Haeberli"-style, we must write these for passes
            // beyond the first, or the initial passes will "show through" the
            // later ones.
            if (writeTransparentPixels)
                buffer.setRGBA(x, yBegin, 0, 0, 0, 0);
        }
    }

    // Tell the frame to copy the row data if need be.
    if (repeatCount > 1)
        buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);

    return true;
}
示例#2
0
void LightSource::init(const std::string& vertexPath, const std::string& fragmentPath) {
	shadowShader.compileShaders(vertexPath, fragmentPath, " ");
	shadowShader.addAttribute("vertexPosition");
	shadowShader.linkShaders();
	initTex();
	initFrameBuffer();
}
示例#3
0
文件: xcb.c 项目: lubosz/smalldemo
int main(int argc, char** argv) {
  fullscreen = false;
  grab = false;
  quit = false;
  initScreen();
  initFrameBuffer();
  createGLContext();
  createColorMap();

  createWindow();
  
  createBlankCursor();
  
  int x = 0;
  
  while(x<5000) {
    renderFrame();
    updateWindowTitle();
    x++;
    }
  
  
      /* Cleanup 
    glXDestroyWindow(display, glxwindow);
    xcb_destroy_window(connection, window);
    glXDestroyContext(display, context);
    XCloseDisplay(display);
      */
  
  return 0;
}
void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
                                     unsigned char* rowBuffer,
                                     unsigned char* rowEnd,
                                     unsigned rowNumber,
                                     unsigned repeatCount,
                                     bool writeTransparentPixels)
{
    // The pixel data and coordinates supplied to us are relative to the frame's
    // origin within the entire image size, i.e.
    // (m_reader->frameXOffset(), m_reader->frameYOffset()).
    int x = m_reader->frameXOffset();
    const int y = m_reader->frameYOffset() + rowNumber;

    // Sanity-check the arguments.
    if ((rowBuffer == 0) || (y >= size().height()))
        return;

    // Get the colormap.
    unsigned colorMapSize;
    unsigned char* colorMap;
    m_reader->getColorMap(colorMap, colorMapSize);
    if (!colorMap)
        return;

    // Initialize the frame if necessary.
    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
        return;

    // Write one row's worth of data into the frame.  There is no guarantee that
    // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
    // we must ensure we don't run off the end of either the source data or the
    // row's X-coordinates.
    for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < size().width()); ++sourceAddr, ++x) {
        const unsigned char sourceValue = *sourceAddr;
        if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) {
            const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
            buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
        } else {
            m_currentBufferSawAlpha = true;
            // We may or may not need to write transparent pixels to the buffer.
            // If we're compositing against a previous image, it's wrong, and if
            // we're writing atop a cleared, fully transparent buffer, it's
            // unnecessary; but if we're decoding an interlaced gif and
            // displaying it "Haeberli"-style, we must write these for passes
            // beyond the first, or the initial passes will "show through" the
            // later ones.
            if (writeTransparentPixels)
                buffer.setRGBA(x, y, 0, 0, 0, 0);
        }
    }

    // Tell the frame to copy the row data if need be.
    if (repeatCount > 1)
        buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height()));
}
bool OffscreenRenderer::makeCurrent(int width, int height, bool sampleBuffers)
{
  ASSERT(mainGlWidget);

  // Considering weak graphics cards glClear is faster when the color and depth buffers are not greater then they have to be.
  // So we create an individual buffer for each size in demand.

  std::unordered_map<unsigned int, Buffer>::iterator it = renderBuffers.find(width << 16 | height << 1 | (sampleBuffers ? 1 : 0));
  if(it == renderBuffers.end())
  {
    Buffer& buffer = renderBuffers[width << 16 | height << 1 | (sampleBuffers ? 1 : 0)];

#ifdef FIX_MACOS_BROKEN_TEXTURES_ON_NVIDIA_BUG
    if(!initFrameBuffer(width, height, buffer))
      if(!initPixelBuffer(width, height, sampleBuffers, buffer))
#else
    if(!initPixelBuffer(width, height, sampleBuffers, buffer))
      if(!initFrameBuffer(width, height, buffer))
#endif
        initHiddenWindow(width, height, buffer);

    return true;
  }
  else
  {
    Buffer& buffer = it->second;
    if(buffer.pbuffer)
      return buffer.pbuffer->makeCurrent();
    if(buffer.frameBufferId)
    {
      mainGlWidget->makeCurrent();
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer.frameBufferId);
      return true;
    }
    if(buffer.glWidget)
      buffer.glWidget->makeCurrent();
    else
      mainGlWidget->makeCurrent();
    return true;
  }
}
void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
{
    // Initialize the frame if necessary.  Some GIFs insert do-nothing frames,
    // in which case we never reach haveDecodedRow() before getting here.
    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    IntRect& rect = m_rects[frameIndex];
    if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
        return;

    buffer.setStatus(RGBA32Buffer::FrameComplete);
    buffer.setDuration(frameDuration);
    buffer.setDisposalMethod(disposalMethod);

    if (!m_currentBufferSawAlpha) {
        // The whole frame was non-transparent, so it's possible that the entire
        // resulting buffer was non-transparent, and we can setHasAlpha(false).
        if (rect.contains(IntRect(IntPoint(), size())))
            buffer.setHasAlpha(false);
        else if (frameIndex > 0) {
            // Tricky case.  This frame does not have alpha only if everywhere
            // outside its rect doesn't have alpha.  To know whether this is
            // true, we check the start state of the frame -- if it doesn't have
            // alpha, we're safe.
            //
            // First skip over prior DisposeOverwritePrevious frames (since they
            // don't affect the start state of this frame) the same way we do in
            // initFrameBuffer().
            const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
            const IntRect* prevRect = &m_rects[frameIndex];
            while ((frameIndex > 0)
                   && (prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)) {
                prevBuffer = &m_frameBufferCache[--frameIndex];
                prevRect = &m_rects[frameIndex];
            }

            // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then
            // we can say we have no alpha if that frame had no alpha.  But
            // since in initFrameBuffer() we already copied that frame's alpha
            // state into the current frame's, we need do nothing at all here.
            //
            // The only remaining case is a DisposeOverwriteBgcolor frame.  If
            // it had no alpha, and its rect is contained in the current frame's
            // rect, we know the current frame has no alpha.
            if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor)
                && !prevBuffer->hasAlpha() && rect.contains(*prevRect))
                buffer.setHasAlpha(false);
        }
    }
}
示例#7
0
ImageFrame* WEBPImageDecoder::frameBufferAtIndex(size_t index)
{
    if (index >= frameCount())
        return 0;

    ImageFrame& frame = m_frameBufferCache[index];
    if (frame.status() == ImageFrame::FrameComplete)
        return &frame;

    Vector<size_t> framesToDecode;
    size_t frameToDecode = index;
    do {
        framesToDecode.append(frameToDecode);
        frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFrameIndex();
    } while (frameToDecode != kNotFound && m_frameBufferCache[frameToDecode].status() != ImageFrame::FrameComplete);

    ASSERT(m_demux);
    for (size_t i = framesToDecode.size(); i > 0; --i) {
        size_t frameIndex = framesToDecode[i - 1];
        if ((m_formatFlags & ANIMATION_FLAG) && !initFrameBuffer(frameIndex))
            return 0;
        WebPIterator webpFrame;
        if (!WebPDemuxGetFrame(m_demux, frameIndex + 1, &webpFrame))
            return 0;
        PlatformInstrumentation::willDecodeImage("WEBP");
        decode(webpFrame.fragment.bytes, webpFrame.fragment.size, false, frameIndex);
        PlatformInstrumentation::didDecodeImage();
        WebPDemuxReleaseIterator(&webpFrame);

        if (failed())
            return 0;

        // We need more data to continue decoding.
        if (m_frameBufferCache[frameIndex].status() != ImageFrame::FrameComplete)
            break;
    }

    // It is also a fatal error if all data is received and we have decoded all
    // frames available but the file is truncated.
    if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() && m_demux && m_demuxState != WEBP_DEMUX_DONE)
        setFailed();

    frame.notifyBitmapIfPixelsChanged();
    return &frame;
}
示例#8
0
LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HDC dstDc;
    PAINTSTRUCT paintInfo;
    BOOL result;

    switch (msg)
    {
    case WM_CREATE:
        if (initFrameBuffer())
            return -1;

        if (!SetTimer(window, SCREEN_UPDATE_TIMER_ID, USER_TIMER_MINIMUM, NULL))
        {
            reportSysError(_T("Failed to create the display update timer."));
            return -1;
        }

        break;
    case WM_DESTROY:
        deinitialize();
        PostQuitMessage(exitCode);
        break;
    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            DestroyWindow(window);
        break;
    case WM_TIMER:
        InvalidateRect(window, NULL, FALSE);
        break;
    case WM_PAINT:
        dstDc = BeginPaint(window, &paintInfo);
        updateScreen();
        BitBlt(dstDc, - (int) bufOffset, 0, WIDTH, HEIGHT, bufDc, 0, 0, SRCCOPY);
        EndPaint(window, &paintInfo);
        updateFps();

        break;
    default:
        return DefWindowProc(window, msg, wParam, lParam);
    }

    return 0;
}
示例#9
0
void WEBPImageDecoder::decode(size_t index) {
  if (failed())
    return;

  Vector<size_t> framesToDecode;
  size_t frameToDecode = index;
  do {
    framesToDecode.append(frameToDecode);
    frameToDecode =
        m_frameBufferCache[frameToDecode].requiredPreviousFrameIndex();
  } while (frameToDecode != kNotFound &&
           m_frameBufferCache[frameToDecode].getStatus() !=
               ImageFrame::FrameComplete);

  ASSERT(m_demux);
  for (auto i = framesToDecode.rbegin(); i != framesToDecode.rend(); ++i) {
    if ((m_formatFlags & ANIMATION_FLAG) && !initFrameBuffer(*i))
      return;
    WebPIterator webpFrame;
    if (!WebPDemuxGetFrame(m_demux, *i + 1, &webpFrame)) {
      setFailed();
    } else {
      decodeSingleFrame(webpFrame.fragment.bytes, webpFrame.fragment.size, *i);
      WebPDemuxReleaseIterator(&webpFrame);
    }
    if (failed())
      return;

    // We need more data to continue decoding.
    if (m_frameBufferCache[*i].getStatus() != ImageFrame::FrameComplete)
      break;

    if (m_purgeAggressively)
      clearCacheExceptFrame(*i);
  }

  // It is also a fatal error if all data is received and we have decoded all
  // frames available but the file is truncated.
  if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() &&
      m_demux && m_demuxState != WEBP_DEMUX_DONE)
    setFailed();
}
示例#10
0
bool GIFImageDecoder::frameComplete(size_t frameIndex)
{
    // Initialize the frame if necessary.  Some GIFs insert do-nothing frames,
    // in which case we never reach haveDecodedRow() before getting here.
    ImageFrame& buffer = m_frameBufferCache[frameIndex];
    if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex))
        return false; // initFrameBuffer() has already called setFailed().

    buffer.setStatus(ImageFrame::FrameComplete);

    if (!m_currentBufferSawAlpha) {
        // The whole frame was non-transparent, so it's possible that the entire
        // resulting buffer was non-transparent, and we can setHasAlpha(false).
        if (buffer.originalFrameRect().contains(IntRect(IntPoint(), size()))) {
            buffer.setHasAlpha(false);
            buffer.setRequiredPreviousFrameIndex(notFound);
        } else if (buffer.requiredPreviousFrameIndex() != notFound) {
            // Tricky case.  This frame does not have alpha only if everywhere
            // outside its rect doesn't have alpha.  To know whether this is
            // true, we check the start state of the frame -- if it doesn't have
            // alpha, we're safe.
            const ImageFrame* prevBuffer = &m_frameBufferCache[buffer.requiredPreviousFrameIndex()];
            ASSERT(prevBuffer->disposalMethod() != ImageFrame::DisposeOverwritePrevious);

            // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then
            // we can say we have no alpha if that frame had no alpha.  But
            // since in initFrameBuffer() we already copied that frame's alpha
            // state into the current frame's, we need do nothing at all here.
            //
            // The only remaining case is a DisposeOverwriteBgcolor frame.  If
            // it had no alpha, and its rect is contained in the current frame's
            // rect, we know the current frame has no alpha.
            if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuffer->originalFrameRect()))
                buffer.setHasAlpha(false);
        }
    }

    return true;
}
示例#11
0
void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
                                     unsigned char* rowBuffer,   // Pointer to single scanline temporary buffer
                                     unsigned char* rowEnd,
                                     unsigned rowNumber,  // The row index
                                     unsigned repeatCount) // How many times to repeat the row
{
    // Resize to the width and height of the image.
    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    RGBA32Buffer* previousBuffer = (frameIndex > 0) ? &m_frameBufferCache[frameIndex-1] : 0;
    bool compositeWithPreviousFrame = previousBuffer && previousBuffer->includeInNextFrame();

    if (buffer.status() == RGBA32Buffer::FrameEmpty)
        initFrameBuffer(buffer, previousBuffer, compositeWithPreviousFrame);

    if (rowBuffer == 0)
      return;

    unsigned colorMapSize;
    unsigned char* colorMap;
    m_reader->getColorMap(colorMap, colorMapSize);
    if (!colorMap)
        return;

    // The buffers that we draw are the entire image's width and height, so a final output frame is
    // width * height RGBA32 values in size.
    //
    // A single GIF frame, however, can be smaller than the entire image, i.e., it can represent some sub-rectangle
    // within the overall image.  The rows we are decoding are within this
    // sub-rectangle.  This means that if the GIF frame's sub-rectangle is (x,y,w,h) then row 0 is really row
    // y, and each row goes from x to x+w.
    unsigned dstPos = (m_reader->frameYOffset() + rowNumber) * m_size.width() + m_reader->frameXOffset();
    unsigned* dst = buffer.bytes().data() + dstPos;
    unsigned* currDst = dst;
    unsigned char* currentRowByte = rowBuffer;
    
    bool hasAlpha = m_reader->isTransparent(); 
    bool sawAlpha = false;
    while (currentRowByte != rowEnd) {
        if ((!hasAlpha || *currentRowByte != m_reader->transparentPixel()) && *currentRowByte < colorMapSize) {
            unsigned colorIndex = *currentRowByte * 3;
            unsigned red = colorMap[colorIndex];
            unsigned green = colorMap[colorIndex + 1];
            unsigned blue = colorMap[colorIndex + 2];
            RGBA32Buffer::setRGBA(*currDst, red, green, blue, 255);
        } else {
            if (!sawAlpha) {
                sawAlpha = true;
                buffer.setHasAlpha(true);
            }
            
            if (!compositeWithPreviousFrame)
                RGBA32Buffer::setRGBA(*currDst, 0, 0, 0, 0);
        }
        currDst++;
        currentRowByte++;
    }

    if (repeatCount > 1) {
        // Copy the row |repeatCount|-1 times.
        unsigned size = (currDst - dst) * sizeof(unsigned);
        unsigned width = m_size.width();
        unsigned* end = buffer.bytes().data() + width * m_size.height();
        currDst = dst + width;
        for (unsigned i = 1; i < repeatCount; i++) {
            if (currDst + size > end) // Protect against a buffer overrun from a bogus repeatCount.
                break;
            memcpy(currDst, dst, size);
            currDst += width;
        }
    }

    // Our partial height is rowNumber + 1, e.g., row 2 is the 3rd row, so that's a height of 3.
    // Adding in repeatCount - 1 to rowNumber + 1 works out to just be rowNumber + repeatCount.
    buffer.ensureHeight(rowNumber + repeatCount);
}
示例#12
0
bool GIFImageDecoder::haveDecodedRow(size_t frameIndex, const Vector<unsigned char>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels)
{
    const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex);
    // The pixel data and coordinates supplied to us are relative to the frame's
    // origin within the entire image size, i.e.
    // (frameContext->xOffset, frameContext->yOffset). There is no guarantee
    // that width == (size().width() - frameContext->xOffset), so
    // we must ensure we don't run off the end of either the source data or the
    // row's X-coordinates.
    int xBegin = frameContext->xOffset;
    int yBegin = frameContext->yOffset + rowNumber;
    int xEnd = std::min(static_cast<int>(frameContext->xOffset + width), size().width());
    int yEnd = std::min(static_cast<int>(frameContext->yOffset + rowNumber + repeatCount), size().height());
    if (rowBuffer.isEmpty() || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
        return true;

    // Get the colormap.
    const unsigned char* colorMap;
    unsigned colorMapSize;
    if (frameContext->isLocalColormapDefined) {
        colorMap = m_reader->localColormap(frameContext);
        colorMapSize = m_reader->localColormapSize(frameContext);
    } else {
        colorMap = m_reader->globalColormap();
        colorMapSize = m_reader->globalColormapSize();
    }
    if (!colorMap)
        return true;

    // Initialize the frame if necessary.
    ImageFrame& buffer = m_frameBufferCache[frameIndex];
    if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex))
        return false;

    ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin);
    // Write one row's worth of data into the frame.  
    for (int x = xBegin; x < xEnd; ++x) {
        const unsigned char sourceValue = rowBuffer[x - frameContext->xOffset];
        if ((!frameContext->isTransparent || (sourceValue != frameContext->tpixel)) && (sourceValue < colorMapSize)) {
            const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
            buffer.setRGBA(currentAddress, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
        } else {
            m_currentBufferSawAlpha = true;
            // We may or may not need to write transparent pixels to the buffer.
            // If we're compositing against a previous image, it's wrong, and if
            // we're writing atop a cleared, fully transparent buffer, it's
            // unnecessary; but if we're decoding an interlaced gif and
            // displaying it "Haeberli"-style, we must write these for passes
            // beyond the first, or the initial passes will "show through" the
            // later ones.
            if (writeTransparentPixels)
                buffer.setRGBA(currentAddress, 0, 0, 0, 0);
        }
        ++currentAddress;
    }

    // Tell the frame to copy the row data if need be.
    if (repeatCount > 1)
        buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);

    return true;
}
示例#13
0
bool GIFImageDecoder::haveDecodedRow(size_t frameIndex, GIFRow::const_iterator rowBegin, size_t width, size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels)
{
    const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex);
    // The pixel data and coordinates supplied to us are relative to the frame's
    // origin within the entire image size, i.e.
    // (frameContext->xOffset, frameContext->yOffset). There is no guarantee
    // that width == (size().width() - frameContext->xOffset), so
    // we must ensure we don't run off the end of either the source data or the
    // row's X-coordinates.
    const int xBegin = frameContext->xOffset();
    const int yBegin = frameContext->yOffset() + rowNumber;
    const int xEnd = std::min(static_cast<int>(frameContext->xOffset() + width), size().width());
    const int yEnd = std::min(static_cast<int>(frameContext->yOffset() + rowNumber + repeatCount), size().height());
    if (!width || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
        return true;

    const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefined() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table();

    if (colorTable.isEmpty())
        return true;

    GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin();

    // Initialize the frame if necessary.
    ImageFrame& buffer = m_frameBufferCache[frameIndex];
    if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex))
        return false;

    const size_t transparentPixel = frameContext->transparentPixel();
    GIFRow::const_iterator rowEnd = rowBegin + (xEnd - xBegin);
    ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin);

    // We may or may not need to write transparent pixels to the buffer.
    // If we're compositing against a previous image, it's wrong, and if
    // we're writing atop a cleared, fully transparent buffer, it's
    // unnecessary; but if we're decoding an interlaced gif and
    // displaying it "Haeberli"-style, we must write these for passes
    // beyond the first, or the initial passes will "show through" the
    // later ones.
    //
    // The loops below are almost identical. One writes a transparent pixel
    // and one doesn't based on the value of |writeTransparentPixels|.
    // The condition check is taken out of the loop to enhance performance.
    // This optimization reduces decoding time by about 15% for a 3MB image.
    if (writeTransparentPixels) {
        for (; rowBegin != rowEnd; ++rowBegin, ++currentAddress) {
            const size_t sourceValue = *rowBegin;
            if ((sourceValue != transparentPixel) && (sourceValue < colorTable.size())) {
                *currentAddress = colorTableIter[sourceValue];
            } else {
                *currentAddress = 0;
                m_currentBufferSawAlpha = true;
            }
        }
    } else {
        for (; rowBegin != rowEnd; ++rowBegin, ++currentAddress) {
            const size_t sourceValue = *rowBegin;
            if ((sourceValue != transparentPixel) && (sourceValue < colorTable.size()))
                *currentAddress = colorTableIter[sourceValue];
            else
                m_currentBufferSawAlpha = true;
        }
    }

    // Tell the frame to copy the row data if need be.
    if (repeatCount > 1)
        buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);

    buffer.setPixelsChanged(true);
    return true;
}
示例#14
0
void resize(int width,int height) {
	releaseFrameBuffer(&frameBuffer);
	initFrameBuffer(&frameBuffer,width,height);

	scrw=width; scrh=height;
}
示例#15
0
//--------------------------------------------------------------
void testApp::setup(){
	ofDisableArbTex();
	ofSetTextureWrap();
	//configure FBO
	initFrameBuffer();
	
	//camera config
#ifdef KINECT
	
	context.setupUsingXMLFile();
	image.setup(&context);
	depth.setup(&context);
	xn::DepthGenerator& depthGen = depth.getXnDepthGenerator();
	xn::ImageGenerator& imageGen = image.getXnImageGenerator();
	
	
	XnStatus ret = xnSetViewPoint(depthGen, imageGen);
	cout << "Using kinect" << endl;

#else
	//ofSetLogLevel(OF_LOG_VERBOSE);
	//grabber.listDevices();
	//grabber.setDeviceID(7);
	if(grabber.initGrabber(640, 480)){
		
	
		cout << "Using grabber" << endl;
		
	} else {
		cout << "MASSIVE FAIL" <<endl;
		
	}
	
#endif
	
	
	convert.allocate(640, 480);				//conversion of camera image to grayscale
	gray.allocate(640, 480);				//grayscale tracking image
	kinectImage.allocate(640, 480);			//image from kinect
	kinectDepthImage.allocate(640, 480);	//Depth image from kinect
	finalMaskImage.allocate(640, 480);;		//final composition mask
	sceneDepthImage.allocate(640, 480);;	//scenes depthmap image
	finalImage.allocate(640, 480);
	sceneImage.allocate(640,480);
	
	pixelBuf = new unsigned char[640*480];			//temp buffer for kinect depth strea
	colorPixelBuf = new unsigned char[640*480*3];	//temp buffer for kinect image
	sceneDepthBuf = new unsigned short[640 * 480];	//depth buffer from our rendered scene
	kinectDepthBuf = new unsigned short[640 * 480];	//camera image buffer
	finalBuf = new unsigned char[640 * 480];		//final mask buffer
	finalImageBuf = new unsigned char[640 * 480 * 3];	//final Image buffer
	sceneBuffer = new unsigned char[640 * 480 * 3];		//copy of the scene in the FBO	
	
	bDraw = false;
	
	//tracker = new ARToolKitPlus::TrackerSingleMarkerImpl<6,6,6, 1, 8>(width,height);
	tracker = new ARToolKitPlus::TrackerMultiMarkerImpl<6,6,6, 1, 64>(width,height);
	
	tracker->setPixelFormat(ARToolKitPlus::PIXEL_FORMAT_LUM);	
	//markerboard_480-499.cfg
    if( !tracker->init( (const char *)ofToDataPath("bluedot.cfg").c_str(), (const char *)ofToDataPath("conf.cfg").c_str(), 1.0f, 1000.0f) )            // load std. ARToolKit camera file
	{
		printf("ERROR: init() failed\n");
		delete tracker;
		return;
	}
	// the marker in the BCH test image has a thin border...
    tracker->setBorderWidth(0.125f);	
    // set a threshold. alternatively we could also activate automatic thresholding
    //tracker->setThreshold(150);	
	tracker->activateAutoThreshold(true);
    // let's use lookup-table undistortion for high-speed
    // note: LUT only works with images up to 1024x1024
    tracker->setUndistortionMode(ARToolKitPlus::UNDIST_LUT);
	
    // RPP is more robust than ARToolKit's standard pose estimator
    tracker->setPoseEstimator(ARToolKitPlus::POSE_ESTIMATOR_RPP);
	
	tracker->setImageProcessingMode(ARToolKitPlus::IMAGE_FULL_RES);
	
    // switch to simple ID based markers
    // use the tool in tools/IdPatGen to generate markers
    tracker->setMarkerMode(ARToolKitPlus::MARKER_ID_SIMPLE);
	
	
	netThread = new NetworkThread(this);
	netThread->start();
	
	//load textures
	ofDisableArbTex();
	ofSetTextureWrap();
	textures[0].loadImage("grass.png");
	textures[1].loadImage("cobble.png");	
	textures[2].loadImage("dirt.png");	
	textures[3].loadImage("lava.png");	
	textures[4].loadImage("rock.png");	
	textures[5].loadImage("sand.png");	
	textures[6].loadImage("snow.png");	
	textures[7].loadImage("tree.png");
	textures[8].loadImage("leaves.png");
	
	
	mapWidth = 20;
	mapHeight = 20;
	mapDepth = 20;
	mapLocked = false;
	
	//fill our 3d vector with 20x20x20
	mapLocked = true;
	array3D.resize(mapWidth);
	for (int i = 0; i < mapWidth; ++i) {
		array3D[i].resize(mapHeight);
		
		for (int j = 0; j < mapHeight; ++j)
			array3D[i][j].resize(mapDepth);
	}
	
	//create block face data and clear map 
	Block b;	
	
	vList[0] = ofxVec3f(0.0f, 0.0f, -1.0f);
	vList[1] = ofxVec3f(-1.0f, 0.0f, -1.0f);
	vList[2] = ofxVec3f(-1.0f, 0.0f, 0.0f);
	vList[3] = ofxVec3f(0.0f, 0.0f, 0.0f);
	vList[4] = ofxVec3f(-1.0f, -1.0f, 0.0f);
	vList[5] = ofxVec3f(0.0f, -1.0f, 0.0f);
	vList[6] = ofxVec3f(0.0f, -1.0f, -1.0f);
	vList[7] = ofxVec3f(-1.0f, -1.0f, -1.0f);
	
	//vertex indices for faces
	const static int faceVals[6][4] = {
		{2, 1, 0, 3}, //top
		{5, 4, 2, 3}, //front
		{0, 6, 5, 3},//right
		{4, 7, 1, 2},//left
		{5, 6, 7, 5},//bottom
		{0, 1, 7, 6} //back
	};
		
	
	for(int x=0; x < mapWidth; x++){
		for(int y=0; y < mapHeight; y++){
			for(int z=0; z < mapDepth; z++){
				b.type = NONE;
				b.textured = false;
				b.visMask = VIS_TOP;
				
				
				for(int a = 0; a < 6; a++){
					for (int c = 0; c < 4; c++){
						b.faceList[a][c] = faceVals[a][c];
					}
				}
				
				
				array3D[x][y][z] = b;		
				
			}
		}
	}
	
	//add some test blocks to play with when offline
	b.type = GRASS;
	b.textured = true;
	b.textureRef = 0;
	b.visMask = 63;
	array3D[1][1][5] = b;	
	array3D[2][1][5] = b;
	array3D[3][1][5] = b;
	array3D[4][1][5] = b;
	array3D[5][1][5] = b;
	array3D[6][1][5] = b;

	//testBlock = b;
	
	//run the face visibility and normal calculations
	updateVisibility();
	
	//dont draw the gui
	guiDraw = false;
	
	//scale and offset for map
	mapScale = 1.0f;
	offset.x = -100.0f;
	offset.y = 100.0f;
	
	scVal = 1.0f;
	
	//used as light colour (when lights eventually work)
	sceneWhiteLevel = ofColor(255,255,255);
	
	#ifdef SYPHON
	//start up syphon and set framerate
	mainOutputSyphonServer.setName("Minecraft");
	#endif
	
	ofSetFrameRate(60);
	
	//try and set up some lights
	
	light light = {
		{0,50,0,1},  //position (the final 1 means the light is positional)
		{1,1,1,1},    //diffuse
		{0,0,0,1},    //specular
		{0,0,0,1}     //ambient
    };
	
	light0 = light;
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	//glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0);  //sets lighting to one-sided
	glLightfv(GL_LIGHT0, GL_POSITION, light0.pos);
	doLights();
	
	
	//turn on backface culling
	glEnable(GL_CULL_FACE);
	
}
示例#16
0
void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
                                     unsigned char* rowBuffer,   // Pointer to single scanline temporary buffer
                                     unsigned char* rowEnd,
                                     unsigned rowNumber,  // The row index
                                     unsigned repeatCount,  // How many times to repeat the row
                                     bool writeTransparentPixels)
{
    // Initialize the frame if necessary.
    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    if (buffer.status() == RGBA32Buffer::FrameEmpty)
        initFrameBuffer(frameIndex);

    // 7/13/09 CSidhall - Alloc fail handling
    if(!buffer.bytes().data())
        return;

    // Do nothing for bogus data.
    if (rowBuffer == 0 || static_cast<int>(m_reader->frameYOffset() + rowNumber) >= m_size.height())
      return;

    unsigned colorMapSize;
    unsigned char* colorMap;
    m_reader->getColorMap(colorMap, colorMapSize);
    if (!colorMap)
        return;

    // The buffers that we draw are the entire image's width and height, so a final output frame is
    // width * height RGBA32 values in size.
    //
    // A single GIF frame, however, can be smaller than the entire image, i.e., it can represent some sub-rectangle
    // within the overall image.  The rows we are decoding are within this
    // sub-rectangle.  This means that if the GIF frame's sub-rectangle is (x,y,w,h) then row 0 is really row
    // y, and each row goes from x to x+w.
    unsigned dstPos = (m_reader->frameYOffset() + rowNumber) * m_size.width() + m_reader->frameXOffset();
    unsigned* dst = buffer.bytes().data() + dstPos;
    unsigned* dstEnd = dst + m_size.width() - m_reader->frameXOffset();
    unsigned* currDst = dst;
    unsigned char* currentRowByte = rowBuffer;
    
    while (currentRowByte != rowEnd && currDst < dstEnd) {
        if ((!m_reader->isTransparent() || *currentRowByte != m_reader->transparentPixel()) && *currentRowByte < colorMapSize) {
            unsigned colorIndex = *currentRowByte * 3;
            unsigned red = colorMap[colorIndex];
            unsigned green = colorMap[colorIndex + 1];
            unsigned blue = colorMap[colorIndex + 2];
            RGBA32Buffer::setRGBA(*currDst, red, green, blue, 255);
        } else {
            m_currentBufferSawAlpha = true;
            // We may or may not need to write transparent pixels to the buffer.
            // If we're compositing against a previous image, it's wrong, and if
            // we're writing atop a cleared, fully transparent buffer, it's
            // unnecessary; but if we're decoding an interlaced gif and
            // displaying it "Haeberli"-style, we must write these for passes
            // beyond the first, or the initial passes will "show through" the
            // later ones.
            if (writeTransparentPixels)
                RGBA32Buffer::setRGBA(*currDst, 0, 0, 0, 0);
        }
        currDst++;
        currentRowByte++;
    }

    if (repeatCount > 1) {
        // Copy the row |repeatCount|-1 times.
        unsigned num = currDst - dst;
        unsigned size = num * sizeof(unsigned);
        unsigned width = m_size.width();
        unsigned* end = buffer.bytes().data() + width * m_size.height();
        currDst = dst + width;
        for (unsigned i = 1; i < repeatCount; i++) {
            if (currDst + num > end) // Protect against a buffer overrun from a bogus repeatCount.
                break;
            memcpy(currDst, dst, size);
            currDst += width;
        }
    }

    // Our partial height is rowNumber + 1, e.g., row 2 is the 3rd row, so that's a height of 3.
    // Adding in repeatCount - 1 to rowNumber + 1 works out to just be rowNumber + repeatCount.
    buffer.ensureHeight(rowNumber + repeatCount);
}