void djvGlslTestExposureOp::render(const djvImage & in) throw (djvError) { //DJV_DEBUG("djvGlslTestExposureOp::render"); //DJV_DEBUG_PRINT("in = " << in); // Initialize. begin(); _texture.init(in, GL_TEXTURE_RECTANGLE); if (! _init) { _shader.init(vertexSource, fragmentSource); _init = true; } // Render. _shader.bind(); const GLhandleARB program = _shader.program(); const float v = static_cast<float>(djvMath::pow(2.0, _values.exposure + 2.47393)); const float d = static_cast<float>(_values.defog); const float k = static_cast<float>(djvMath::pow(2.0, _values.kneeLow)); const float f = static_cast<float>( kneeF(djvMath::pow(2.0, _values.kneeHigh) - k, djvMath::pow(2.0, 3.5) - k)); const float g = static_cast<float>(1.0 / _values.gamma); //DJV_DEBUG_PRINT("v = " << v); //DJV_DEBUG_PRINT("d = " << d); //DJV_DEBUG_PRINT("k = " << k); //DJV_DEBUG_PRINT("f = " << f); //DJV_DEBUG_PRINT("g = " << g); glUniform1f(glGetUniformLocation(program, "exposure.v"), v); glUniform1f(glGetUniformLocation(program, "exposure.d"), d); glUniform1f(glGetUniformLocation(program, "exposure.k"), k); glUniform1f(glGetUniformLocation(program, "exposure.f"), f); glUniform1f(glGetUniformLocation(program, "exposure.g"), g); glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(_shader.program(), "texture"), 0); _texture.bind(); const djvPixelDataInfo & info = in.info(); djvOpenGlUtil::ortho(info.size); glViewport(0, 0, info.size.x, info.size.y); glClear(GL_COLOR_BUFFER_BIT); djvGlslTestUtil::quad(info); end(); }
void djvPngLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvPngLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); image.colorProfile = djvColorProfile(); image.tags = djvImageTags(); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info; _open(fileName, info); // Read the file. djvPixelData * data = frame.proxy ? &_tmp : ℑ data->set(info); for (int y = 0; y < info.size.y; ++y) { if (! pngScanline(_png, data->data(0, data->h() - 1 - y))) { throw djvError( djvPng::staticName, _pngError.msg); } } pngEnd(_png, _pngInfoEnd); // Proxy scale the image. if (frame.proxy) { info.size = djvPixelDataUtil::proxyScale(info.size, frame.proxy); info.proxy = frame.proxy; image.set(info); djvPixelDataUtil::proxyScale(_tmp, image, frame.proxy); } //DJV_DEBUG_PRINT("image = " << image); close(); }
void djvLutPlugin::kodakLoad(djvFileIo & io, djvImage & out) throw (djvError) { //DJV_DEBUG("djvLutPlugin::kodakLoad"); for (int x = 0; x < out.w(); ++x) { djvColor color(out.pixel()); for (int c = 0; c < djvPixel::channels(out.pixel()); ++c) { char tmp[djvStringUtil::cStringLength] = ""; djvFileIoUtil::word(io, tmp, djvStringUtil::cStringLength); const int v = QString(tmp).toInt(); switch (djvPixel::type(out.pixel())) { case djvPixel::U8: color.setU8(v, c); break; case djvPixel::U10: color.setU10(v, c); break; case djvPixel::U16: color.setU16(v, c); break; default: break; } } //DJV_DEBUG_PRINT(x << " = " << color); djvMemory::copy( color.data(), out.data(x, 0), djvPixel::byteCount(out.pixel())); } }
void djvGlslTestColorOp::render(const djvImage & in) throw (djvError) { //DJV_DEBUG("djvGlslTestColorOp::render"); //DJV_DEBUG_PRINT("in = " << in); // Initialize. begin(); _texture.init(in); if (! _init) { _shader.init(src); _init = true; } // Render. _shader.bind(); const double b = _value.brightness; const double c = _value.contrast; const double s = _value.saturation; const djvMatrix4f value = djvOpenGlImageColor::brightnessMatrix(b, b, b) * djvOpenGlImageColor::contrastMatrix(c, c, c) * djvOpenGlImageColor::saturationMatrix(s, s, s); glUniformMatrix4fv( glGetUniformLocation(_shader.program(), "color"), 1, false, djvMatrixUtil::convert<double, GLfloat>(djvMatrixUtil::transpose(value)).e); glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(_shader.program(), "texture"), 0); _texture.bind(); const djvPixelDataInfo & info = in.info(); djvOpenGlUtil::ortho(info.size); glViewport(0, 0, info.size.x, info.size.y); glClear(GL_COLOR_BUFFER_BIT); djvGlslTestUtil::quad(info); end(); }
void djvLutLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvLutLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); image.colorProfile = djvColorProfile(); image.tags = djvImageTags(); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); djvImageIoInfo info; djvFileIo io; _open(fileName, info, io); // Read the file. image.set(info); switch (_format) { case djvLut::FORMAT_INFERNO: djvLut::infernoLoad(io, image); break; case djvLut::FORMAT_KODAK: djvLut::kodakLoad(io, image); break; default: break; } //DJV_DEBUG_PRINT("image = " << image); }
void djvDpxLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvDpxLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info; QScopedPointer<djvFileIo> io(new djvFileIo); _open(fileName, info, *io); image.tags = info.tags; // Set the color profile. if ((djvCineon::COLOR_PROFILE_FILM_PRINT == _options.inputColorProfile) || (djvCineon::COLOR_PROFILE_AUTO == _options.inputColorProfile && _filmPrint)) { //DJV_DEBUG_PRINT("color profile"); image.colorProfile.type = djvColorProfile::LUT; if (! _filmPrintLut.isValid()) { _filmPrintLut = djvCineon::filmPrintToLinearLut( _options.inputFilmPrint); } image.colorProfile.lut = _filmPrintLut; } else { image.colorProfile = djvColorProfile(); } // Read the file. io->readAhead(); bool mmap = true; if ((io->size() - io->pos()) < djvPixelDataUtil::dataByteCount(info)) { mmap = false; } //DJV_DEBUG_PRINT("mmap = " << mmap); if (mmap) { if (! frame.proxy) { image.set(info, io->mmapP(), io.data()); io.take(); } else { _tmp.set(info, io->mmapP()); info.size = djvPixelDataUtil::proxyScale(info.size, frame.proxy); info.proxy = frame.proxy; image.set(info); djvPixelDataUtil::proxyScale(_tmp, image, frame.proxy); } } else { djvPixelData * data = frame.proxy ? &_tmp : ℑ data->set(info); djvError error; bool errorValid = false; try { for (int y = 0; y < info.size.y; ++y) { io->get( data->data(0, y), info.size.x * djvPixel::byteCount(info.pixel)); } } catch (const djvError & otherError) { error = otherError; errorValid = true; } if (frame.proxy) { info.size = djvPixelDataUtil::proxyScale(info.size, frame.proxy); info.proxy = frame.proxy; image.set(info); djvPixelDataUtil::proxyScale(_tmp, image, frame.proxy); } if (errorValid) throw error; } //DJV_DEBUG_PRINT("image = " << image); }
void djvCineonSave::write(const djvImage & in, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvCineonSave::write"); //DJV_DEBUG_PRINT("in = " << in); //DJV_DEBUG_PRINT("frame = " << frame); // Set the color profile. djvColorProfile colorProfile; if (djvCineon::COLOR_PROFILE_FILM_PRINT == _options.outputColorProfile || djvCineon::COLOR_PROFILE_AUTO == _options.outputColorProfile) { //DJV_DEBUG_PRINT("color profile"); colorProfile.type = djvColorProfile::LUT; colorProfile.lut = djvCineon::linearToFilmPrintLut( _options.outputFilmPrint); } // Open the file. const QString fileName = _file.fileName(frame.frame); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info(_info); info.fileName = fileName; info.tags = in.tags; djvFileIo io; io.open(fileName, djvFileIo::WRITE); _header = djvCineonHeader(); _header.save(io, info, _options.outputColorProfile); // Convert. const djvPixelData * p = ∈ if ( in.info() != _info || in.colorProfile.type != djvColorProfile::RAW || colorProfile.type != djvColorProfile::RAW) { //DJV_DEBUG_PRINT("convert = " << _image); _image.zero(); djvOpenGlImageOptions options; options.colorProfile = colorProfile; djvOpenGlImage::copy(*p, _image, options); p = &_image; } // Write the file. io.set(p->data(), p->dataByteCount()); _header.saveEnd(io); }
void djvIffSave::write(const djvImage & in, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvIffSave::write"); //DJV_DEBUG_PRINT("in = " << in); // Open the file. djvFileIo io; io.setEndian(djvMemory::endian() != djvMemory::MSB); io.open(_file.fileName(frame.frame), djvFileIo::WRITE); djvIff::saveInfo( io, _info, _options.compression != djvIff::COMPRESSION_NONE); // Convert the image. const djvPixelData * p = ∈ if (in.info() != _info) { //DJV_DEBUG_PRINT("convert = " << _image); _image.zero(); djvOpenGlImage::copy(in, _image); p = &_image; } // Write the file. const int w = p->w(), h = p->h(); const int channels = djvPixel::channels(p->info().pixel); const int channelByteCount = djvPixel::channelByteCount(p->info().pixel); const int byteCount = djvPixel::byteCount(p->info().pixel); const bool compress = _options.compression ? true : false; quint32 length = 0; //DJV_DEBUG_PRINT("channels = " << channels); //DJV_DEBUG_PRINT("channelByteCount = " << channelByteCount); //DJV_DEBUG_PRINT("byteCount = " << byteCount); quint64 pos = 0; pos = io.pos(); //DJV_DEBUG_PRINT("pos = " << static_cast<int>(pos)); // 'FOR4' type io.setU8('F'); io.setU8('O'); io.setU8('R'); io.setU8('4'); // 'FOR4' length // NOTE: only reserved for now. io.setU32(length); // 'TBMP' type io.setU8('T'); io.setU8('B'); io.setU8('M'); io.setU8('P'); // Write tiles. djvVector2i size = djvIff::tileSize(w, h); // Y order. for (int y = 0; y < size.y; y++) { // X order. for (int x = 0; x < size.x; x++) { // Set tile coordinates. quint16 xmin, xmax, ymin, ymax; // Set xmin and xmax. xmin = x * djvIff::tileWidth(); xmax = djvMath::min(xmin + djvIff::tileWidth(), w) - 1; // Set ymin and ymax. ymin = y * djvIff::tileHeight(); ymax = djvMath::min(ymin + djvIff::tileHeight(), h) - 1; // Set width and height. quint32 tw = xmax - xmin + 1; quint32 th = ymax - ymin + 1; // Set type. io.setU8('R'); io.setU8('G'); io.setU8('B'); io.setU8('A'); // Length. quint32 length = tw * th * byteCount; // Tile length. quint32 tileLength = length; // Align. length = djvIff::alignSize(length, 4); // Append xmin, xmax, ymin and ymax. length += 8; // Tile compression. bool tile_compress = compress; // Set bytes. djvMemoryBuffer<quint8> tile(tileLength); quint8 * outP = tile(); // Handle 8-bit data. if (p->info().pixel == djvPixel::RGB_U8 || p->info().pixel == djvPixel::RGBA_U8) { if (tile_compress) { quint32 index = 0, size = 0; // Set bytes. // NOTE: prevent buffer overrun. djvMemoryBuffer<quint8> tmp(tileLength * 2); // Map: RGB(A)8 RGBA to BGRA for (int c = (channels * channelByteCount) - 1; c >= 0; --c) { djvMemoryBuffer<quint8> in(tw * th); quint8 * inP = in(); // Data. for (quint16 py = ymin; py <= ymax; py++) { const quint8 * inDy = p->data(0, py); for (quint16 px = xmin; px <= xmax; px++) { // Get pixel. quint8 pixel; const quint8 * inDx = inDy + px * byteCount + c; djvMemory::copy(inDx, &pixel, 1); // Set pixel. *inP++ = pixel; } } // Compress size = djvIff::writeRle(in(), tmp() + index, tw * th); index += size; } // If size exceeds tile length use uncompressed. if (index < tileLength) { djvMemory::copy(tmp(), tile(), index); // Set tile length. tileLength = index; // Append xmin, xmax, ymin and ymax. length = index + 8; // Set length. quint32 align = djvIff::alignSize(length, 4); if (align > length) { outP = tile() + index; // Pad. for (int i = 0; i < static_cast<int>(align - length); i++) { *outP++ = '\0'; tileLength++; } } } else { tile_compress = false; } } if (!tile_compress) { for (quint16 py = ymin; py <= ymax; py++) { const quint8 * inDy = p->data(0, py); for (quint16 px = xmin; px <= xmax; px++) { // Map: RGB(A)8 RGBA to BGRA for (int c = channels - 1; c >= 0; --c) { // Get pixel. quint8 pixel; const quint8 * inDx = inDy + px * byteCount + c * channelByteCount; djvMemory::copy(inDx, &pixel, 1); // Set pixel. *outP++ = pixel; } } } } } // Handle 16-bit data. else if ( p->info().pixel == djvPixel::RGB_U16 || p->info().pixel == djvPixel::RGBA_U16) { if (tile_compress) { quint32 index = 0, size = 0; // Set bytes. // NOTE: prevent buffer overrun. djvMemoryBuffer<quint8> tmp(tileLength * 2); // Set map. int* map = NULL; if (djvMemory::endian() == djvMemory::LSB) { int rgb16[] = { 0, 2, 4, 1, 3, 5 }; int rgba16[] = { 0, 2, 4, 7, 1, 3, 5, 6 }; if (_info.pixel == djvPixel::RGB_U16) { map = rgb16; } else { map = rgba16; } } else { int rgb16[] = { 1, 3, 5, 0, 2, 4 }; int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 }; if (_info.pixel == djvPixel::RGB_U16) { map = rgb16; } else { map = rgba16; } } // Map: RGB(A)16 RGBA to BGRA for (int c = (channels * channelByteCount) - 1; c >= 0; --c) { int mc = map[c]; djvMemoryBuffer<quint8> in(tw * th); quint8 * inP = in(); // Data. for (quint16 py = ymin; py <= ymax; py++) { const quint8 * inDy = p->data(0, py); for (quint16 px = xmin; px <= xmax; px++) { // Get pixel. quint8 pixel; const quint8 * inDx = inDy + px * byteCount + mc; djvMemory::copy(inDx, &pixel, 1); // Set pixel. *inP++ = pixel; } } // Compress size = djvIff::writeRle(in(), tmp() + index, tw * th); index += size; } // If size exceeds tile length use uncompressed. if (index < tileLength) { djvMemory::copy(tmp(), tile(), index); // Set tile length. tileLength = index; // Append xmin, xmax, ymin and ymax. length = index + 8; // Set length. quint32 align = djvIff::alignSize(length, 4); if (align > length) { outP = tile() + index; // Pad. for ( int i = 0; i < static_cast<int>(align - length); i++) { *outP++ = '\0'; tileLength++; } } } else { tile_compress = false; } } if (!tile_compress) { for (quint16 py = ymin; py <= ymax; py++) { const quint8 * inDy = p->data(0, py); for (quint16 px = xmin; px <= xmax; px++) { // Map: RGB(A)16 RGBA to BGRA for (int c = channels - 1; c >= 0; --c) { quint16 pixel; const quint8 * inDx = inDy + px * byteCount + c * channelByteCount; if (djvMemory::endian() == djvMemory::LSB) { djvMemory::convertEndian(inDx, &pixel, 1, 2); } else { djvMemory::copy(inDx, &pixel, 2); } // Set pixel. *outP++ = pixel; outP++; } } } } } // Set length. io.setU32(length); // Set xmin, xmax, ymin and ymax. io.setU16(xmin); io.setU16(ymin); io.setU16(xmax); io.setU16(ymax); // Write. io.set(tile(), tileLength); } } // Set FOR4 CIMG and FOR4 TBMP size quint32 p0 = io.pos() - 8; quint32 p1 = p0 - pos; // NOTE: FOR4 <size> CIMG io.setPos(4); io.setU32(p0); // NOTE: FOR4 <size> TBMP io.setPos(pos + 4); io.setU32(p1); }
void djvFFmpegSave::write(const djvImage & in, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvFFmpegSave::write"); //DJV_DEBUG_PRINT("in = " << in); //DJV_DEBUG_PRINT("frame = " << frame); // Convert the image if necessary. const djvPixelData * p = ∈ if (in.info() != _info) { //DJV_DEBUG_PRINT("convert = " << _image); _image.zero(); djvOpenGlImage::copy(in, _image); p = &_image; } // Encode the image. avpicture_fill( (AVPicture *)_avFrameRgb, p->data(), _avFrameRgbPixel, p->w(), p->h()); quint64 pixelByteCount = p->pixelByteCount(); quint64 scanlineByteCount = p->scanlineByteCount(); quint64 dataByteCount = p->dataByteCount(); const uint8_t * const data [] = { p->data() + dataByteCount - scanlineByteCount, p->data() + dataByteCount - scanlineByteCount, p->data() + dataByteCount - scanlineByteCount, p->data() + dataByteCount - scanlineByteCount }; const int lineSize [] = { -scanlineByteCount, -scanlineByteCount, -scanlineByteCount, -scanlineByteCount }; sws_scale( _swsContext, //(uint8_t const * const *)_avFrameRgb->data, //_avFrameRgb->linesize, data, lineSize, 0, p->h(), _avFrame->data, _avFrame->linesize); AVCodecContext * avCodecContext = _avStream->codec; djvFFmpeg::Packet packet; packet().data = 0; packet().size = 0; _avFrame->pts = _frame++; _avFrame->quality = avCodecContext->global_quality; int finished = 0; int r = avcodec_encode_video2( avCodecContext, &packet(), _avFrame, &finished); if (r < 0) { throw djvError( djvFFmpeg::staticName, djvFFmpeg::toString(r)); } //DJV_DEBUG_PRINT("finished = " << finished); //DJV_DEBUG_PRINT("size = " << packet().size); //DJV_DEBUG_PRINT("pts = " << static_cast<qint64>(packet().pts)); //DJV_DEBUG_PRINT("dts = " << static_cast<qint64>(packet().dts)); //DJV_DEBUG_PRINT("duration = " << static_cast<qint64>(packet().duration)); // Write the image. packet().pts = av_rescale_q( packet().pts, avCodecContext->time_base, _avStream->time_base); packet().dts = av_rescale_q( packet().dts, avCodecContext->time_base, _avStream->time_base); packet().duration = av_rescale_q( packet().duration, avCodecContext->time_base, _avStream->time_base); packet().stream_index = _avStream->index; r = av_interleaved_write_frame(_avFormatContext, &packet()); if (r < 0) { throw djvError( djvFFmpeg::staticName, djvFFmpeg::toString(r)); } }
void djvTargaLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvTargaLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); image.colorProfile = djvColorProfile(); image.tags = djvImageTags(); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info; QScopedPointer<djvFileIo> io(new djvFileIo); _open(fileName, info, *io); // Read the file. io->readAhead(); djvPixelData * data = frame.proxy ? &_tmp : ℑ if (! _compression) { if ((io->size() - io->pos()) < djvPixelDataUtil::dataByteCount(info)) { throw djvError( djvTarga::staticName, djvImageIo::errorLabels()[djvImageIo::ERROR_READ]); } data->set(info, io->mmapP(), io.data()); io.take(); } else { data->set(info); const quint8 * p = io->mmapP(); const quint8 * const end = io->mmapEnd(); const int channels = djvPixel::channels(info.pixel); for (int y = 0; y < info.size.y; ++y) { //DJV_DEBUG_PRINT("y = " << y); p = djvTarga::readRle( p, end, data->data(0, y), info.size.x, channels); if (! p) { throw djvError( djvTarga::staticName, djvImageIo::errorLabels()[djvImageIo::ERROR_READ]); } } } // Proxy scale the image. if (frame.proxy) { info.size = djvPixelDataUtil::proxyScale(info.size, frame.proxy); info.proxy = frame.proxy; image.set(info); djvPixelDataUtil::proxyScale(_tmp, image, frame.proxy); } //DJV_DEBUG_PRINT("image = " << image); }
void djvSgiLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvSgiLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); image.colorProfile = djvColorProfile(); image.tags = djvImageTags(); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info; djvFileIo io; _open(fileName, info, io); // Read the file. io.readAhead(); const quint64 pos = io.pos(); const quint64 size = io.size() - pos; const int channels = djvPixel::channels(info.pixel); const int bytes = djvPixel::channelByteCount(info.pixel); if (! _compression) { if (1 == bytes) { const quint8 * p = io.mmapP(); io.seek(djvPixelDataUtil::dataByteCount(info)); _tmp.set(info, p); } else { if (size != djvPixelDataUtil::dataByteCount(info)) { throw djvError( djvSgi::staticName, djvImageIo::errorLabels()[djvImageIo::ERROR_READ]); } _tmp.set(info); io.get(_tmp.data(), size / bytes, bytes); } } else { _tmp.set(info); djvMemoryBuffer<quint8> tmp(size); io.get(tmp(), size / bytes, bytes); const quint8 * inP = tmp(); const quint8 * end = inP + size; quint8 * outP = _tmp.data(); for (int c = 0; c < channels; ++c) { //DJV_DEBUG_PRINT("channel = " << c); for (int y = 0; y < info.size.y; ++y, outP += info.size.x * bytes) { //DJV_DEBUG_PRINT("y = " << y); if (! djvSgi::readRle( inP + _rleOffset()[y + info.size.y * c] - pos, end, outP, info.size.x, bytes, io.endian())) { throw djvError( djvSgi::staticName, djvImageIo::errorLabels()[djvImageIo::ERROR_READ]); } } } } // Interleave the image channels. info.size = djvPixelDataUtil::proxyScale(info.size, frame.proxy); info.proxy = frame.proxy; image.set(info); djvPixelDataUtil::planarInterleave(_tmp, image, frame.proxy); //DJV_DEBUG_PRINT("image = " << image); }
void djvRlaLoad::read(djvImage & image, const djvImageIoFrameInfo & frame) throw (djvError) { //DJV_DEBUG("djvRlaLoad::read"); //DJV_DEBUG_PRINT("frame = " << frame); image.colorProfile = djvColorProfile(); image.tags = djvImageTags(); // Open the file. const QString fileName = _file.fileName(frame.frame != -1 ? frame.frame : _file.sequence().start()); //DJV_DEBUG_PRINT("file name = " << fileName); djvImageIoInfo info; djvFileIo io; _open(fileName, info, io); if (frame.layer < 0 || frame.layer >= info.layerCount()) { throw djvError( djvRla::staticName, djvImageIo::errorLabels()[djvImageIo::ERROR_READ]); } djvPixelDataInfo _info = info[frame.layer]; // Read the file. io.readAhead(); djvPixelData * p = frame.proxy ? &_tmp : ℑ p->set(_info); const int w = _info.size.x; const int h = _info.size.y; const int channels = djvPixel::channels(_info.pixel); const int bytes = djvPixel::channelByteCount(_info.pixel); //DJV_DEBUG_PRINT("channels = " << channels); //DJV_DEBUG_PRINT("bytes = " << bytes); quint8 * data_p = p->data(); for (int y = 0; y < h; ++y, data_p += w * channels * bytes) { io.setPos(_rleOffset()[y]); for (int c = 0; c < channels; ++c) { if (djvPixel::F32 == djvPixel::type(_info.pixel)) { djvRla::floatLoad(io, data_p + c * bytes, w, channels); } else { djvRla::readRle(io, data_p + c * bytes, w, channels, bytes); } } } // Proxy scale the image. if (frame.proxy) { _info.size = djvPixelDataUtil::proxyScale(_info.size, frame.proxy); _info.proxy = frame.proxy; image.set(_info); djvPixelDataUtil::proxyScale(_tmp, image, frame.proxy); } //DJV_DEBUG_PRINT("image = " << image); }