void ImageDecoderQt::internalDecodeSize()
{
    ASSERT(m_reader);

    // If we have a QSize() something failed
    QSize size = m_reader->size();
    if (size.isEmpty())
        return failRead();

    m_format = m_reader->format();
    setSize(size.width(), size.height());
}
void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
{
    // Now get the QImage from Qt and place it in the RGBA32Buffer
    QImage img;
    if (!m_reader->read(&img))
        return failRead();

    // now into the RGBA32Buffer - even if the image is not
    QSize imageSize = img.size();
    RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
    buffer->setRect(m_reader->currentImageRect());
    buffer->setStatus(RGBA32Buffer::FrameComplete);
    buffer->setDuration(m_reader->nextImageDelay());
    buffer->setDecodedImage(img);
}
void ImageDecoderQt::internalReadImage(size_t frameIndex)
{
    ASSERT(m_reader);

    if (m_reader->supportsAnimation())
        m_reader->jumpToImage(frameIndex);
    else if (frameIndex != 0)
        return failRead();

    internalHandleCurrentImage(frameIndex);

    // Attempt to return some memory
    for (int i = 0; i < m_frameBufferCache.size(); ++i)
        if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete)
            return;

    delete m_reader;
    delete m_buffer;
    m_buffer = 0;
    m_reader = 0;
}
Ejemplo n.º 4
0
void AsyncPipeReader::handlerReady(uint16_t events) noexcept {
  DestructorGuard dg(this);
  CHECK(events & EventHandler::READ);

  VLOG(5) << "AsyncPipeReader::handlerReady() this=" << this << ", fd=" << fd_;
  assert(readCallback_ != nullptr);

  while (readCallback_) {
    // - What API does callback support?
    const auto movable = readCallback_->isBufferMovable(); // noexcept

    // Get the buffer to read into.
    void* buf = nullptr;
    size_t buflen = 0;
    std::unique_ptr<IOBuf> ioBuf;

    if (movable) {
      ioBuf = IOBuf::create(readCallback_->maxBufferSize());
      buf = ioBuf->writableBuffer();
      buflen = ioBuf->capacity();
    } else {
      try {
        readCallback_->getReadBuffer(&buf, &buflen);
      } catch (const std::exception& ex) {
        AsyncSocketException aex(
            AsyncSocketException::BAD_ARGS,
            string("ReadCallback::getReadBuffer() "
                   "threw exception: ") +
                ex.what());
        failRead(aex);
        return;
      } catch (...) {
        AsyncSocketException aex(
            AsyncSocketException::BAD_ARGS,
            string("ReadCallback::getReadBuffer() "
                   "threw non-exception type"));
        failRead(aex);
        return;
      }
      if (buf == nullptr || buflen == 0) {
        AsyncSocketException aex(
            AsyncSocketException::INVALID_STATE,
            string("ReadCallback::getReadBuffer() "
                   "returned empty buffer"));
        failRead(aex);
        return;
      }
    }

    // Perform the read
#if _WIN32
    // On Windows you can't call read on a socket, so call recv instead.
    ssize_t bytesRead =
        folly::fileutil_detail::wrapNoInt(recv_internal, fd_, buf, buflen);
#else
    ssize_t bytesRead = folly::readNoInt(fd_.toFd(), buf, buflen);
#endif

    if (bytesRead > 0) {
      if (movable) {
        ioBuf->append(std::size_t(bytesRead));
        readCallback_->readBufferAvailable(std::move(ioBuf));
      } else {
        readCallback_->readDataAvailable(size_t(bytesRead));
      }
      // Fall through and continue around the loop if the read
      // completely filled the available buffer.
      // Note that readCallback_ may have been uninstalled or changed inside
      // readDataAvailable().
      if (static_cast<size_t>(bytesRead) < buflen) {
        return;
      }
    } else if (bytesRead < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
      // No more data to read right now.
      return;
    } else if (bytesRead < 0) {
      AsyncSocketException ex(
          AsyncSocketException::INVALID_STATE, "read failed", errno);
      failRead(ex);
      return;
    } else {
      assert(bytesRead == 0);
      // EOF

      unregisterHandler();
      AsyncReader::ReadCallback* callback = readCallback_;
      readCallback_ = nullptr;
      callback->readEOF();
      return;
    }
    // Max reads per loop?
  }
}
Ejemplo n.º 5
0
void AsyncPipeReader::handlerReady(uint16_t events) noexcept {
  DestructorGuard dg(this);
  CHECK(events & EventHandler::READ);

  VLOG(5) << "AsyncPipeReader::handlerReady() this=" << this << ", fd=" << fd_;
  assert(readCallback_ != nullptr);

  while (readCallback_) {
    // Get the buffer to read into.
    void* buf = nullptr;
    size_t buflen = 0;
    try {
      readCallback_->getReadBuffer(&buf, &buflen);
    } catch (const std::exception& ex) {
      AsyncSocketException aex(AsyncSocketException::BAD_ARGS,
                               string("ReadCallback::getReadBuffer() "
                                      "threw exception: ") + ex.what());
      failRead(aex);
      return;
    } catch (...) {
      AsyncSocketException ex(AsyncSocketException::BAD_ARGS,
                              string("ReadCallback::getReadBuffer() "
                                     "threw non-exception type"));
      failRead(ex);
      return;
    }
    if (buf == nullptr || buflen == 0) {
      AsyncSocketException ex(AsyncSocketException::INVALID_STATE,
                              string("ReadCallback::getReadBuffer() "
                                     "returned empty buffer"));
      failRead(ex);
      return;
    }

    // Perform the read
    ssize_t bytesRead = folly::readNoInt(fd_, buf, buflen);
    if (bytesRead > 0) {
      readCallback_->readDataAvailable(bytesRead);
      // Fall through and continue around the loop if the read
      // completely filled the available buffer.
      // Note that readCallback_ may have been uninstalled or changed inside
      // readDataAvailable().
      if (static_cast<size_t>(bytesRead) < buflen) {
        return;
      }
    } else if (bytesRead < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
      // No more data to read right now.
      return;
    } else if (bytesRead < 0) {
      AsyncSocketException ex(AsyncSocketException::INVALID_STATE,
                              "read failed", errno);
      failRead(ex);
      return;
    } else {
      assert(bytesRead == 0);
      // EOF

      unregisterHandler();
      AsyncReader::ReadCallback* callback = readCallback_;
      readCallback_ = nullptr;
      callback->readEOF();
      return;
    }
    // Max reads per loop?
  }
}