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 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 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)); } }