Пример #1
0
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();
}
Пример #2
0
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();
}
Пример #3
0
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 = &in;

    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);
}
Пример #4
0
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 = &in;

    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);
}
Пример #5
0
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 = &in;

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