Пример #1
0
void djvLutPlugin::infernoOpen(djvFileIo & io, djvPixelDataInfo & info, TYPE type)
    throw (djvError)
{
    //DJV_DEBUG("infernoOpen");

    // Header.

    char tmp[djvStringUtil::cStringLength] = "";
    djvFileIoUtil::word(io, tmp, djvStringUtil::cStringLength);

    //DJV_DEBUG_PRINT("magic = " << tmp);

    if (QString(tmp) != "LUT:")
    {
        throw djvError(
            djvLutPlugin::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNRECOGNIZED].
            arg(io.fileName()));
    }

    djvFileIoUtil::word(io, tmp, djvStringUtil::cStringLength);
    const int channels = QString(tmp).toInt();

    djvFileIoUtil::word(io, tmp, djvStringUtil::cStringLength);
    const int size = QString(tmp).toInt();

    //DJV_DEBUG_PRINT("size = " << size);
    //DJV_DEBUG_PRINT("channels = " << channels);

    // Information.

    info.size = djvVector2i(size, 1);

    int bitDepth = 0;

    switch (type)
    {
        case TYPE_AUTO: bitDepth = _bitDepth(io); break;
        case TYPE_U8:   bitDepth = 8;             break;
        case TYPE_U10:  bitDepth = 10;            break;
        case TYPE_U16:  bitDepth = 16;            break;

        default: break;
    }

    //DJV_DEBUG_PRINT("bit depth = " << bitDepth);

    if (! djvPixel::pixel(channels, bitDepth, djvPixel::INTEGER, info.pixel))
    {
        throw djvError(
            djvLutPlugin::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED].
            arg(io.fileName()));
    }
}
Пример #2
0
void djvOpenGlImageShader::init(
    const QString & vertex,
    const QString & fragment) throw (djvError)
{
    if (vertex == _vertex && fragment == _fragment)
        return;

    //DJV_DEBUG("djvOpenGlImageShader::init");
    //DJV_DEBUG_PRINT("fragment = " << fragment);

    del();

    _vertex   = vertex;
    _fragment = fragment;

    GLint error = GL_FALSE;

    _vertexId   = shaderCreate(GL_VERTEX_SHADER);
    _fragmentId = shaderCreate(GL_FRAGMENT_SHADER);

    shaderCompile(_vertexId,   _vertex);
    shaderCompile(_fragmentId, _fragment);

    DJV_DEBUG_OPEN_GL(_program = glCreateProgram());

    if (! _program)
    {
        throw djvError(
            "djvOpenGlImageShader",
            djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_PROGRAM]);
    }

    DJV_DEBUG_OPEN_GL(glAttachShader(_program, _vertexId));
    DJV_DEBUG_OPEN_GL(glAttachShader(_program, _fragmentId));
    DJV_DEBUG_OPEN_GL(glLinkProgram (_program));

    glGetProgramiv(_program, GL_LINK_STATUS, &error);

    char log [4096] = "";
    GLsizei logSize = 0;
    glGetProgramInfoLog(_program, 4096, &logSize, log);

    //DJV_DEBUG_PRINT("log = " << QString(log));

    if (error != GL_TRUE)
    {
        throw djvError(
            "djvOpenGlImageShader",
            djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_PROGRAM].
            arg(log));
    }
}
Пример #3
0
void djvLutLoad::_open(const djvFileInfo & in, djvImageIoInfo & info, djvFileIo & io)
    throw (djvError)
{
    //DJV_DEBUG("djvLutLoad::_open");
    //DJV_DEBUG_PRINT("in = " << in);

    io.open(in, djvFileIo::READ);

    info.fileName = in;
    
    const int index = djvLut::staticExtensions.indexOf(in.extension());

    if (-1 == index)
    {
        throw djvError(
            djvLut::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNRECOGNIZED]);
    }

    _format = static_cast<djvLut::FORMAT>(index);

    switch (_format)
    {
        case djvLut::FORMAT_INFERNO:
            djvLut::infernoOpen(io, info, _options.type);
            break;

        case djvLut::FORMAT_KODAK:
            djvLut::kodakOpen(io, info, _options.type);
            break;

        default: break;
    }
}
Пример #4
0
void djvOpenGlLut::init(const djvPixelDataInfo & info) throw (djvError)
{
    if (info == _info)
        return;

    //DJV_DEBUG("djvOpenGlLut::init");
    //DJV_DEBUG_PRINT("info = " << info);

    del();

    _info = info;
    _size = djvMath::toPow2(_info.size.x);

    //DJV_DEBUG_PRINT("size = " << _size);

    DJV_DEBUG_OPEN_GL(glGenTextures(1, &_id));

    if (! _id)
    {
        throw djvError(
            "djvOpenGlLut",
            qApp->translate("djvOpenGlLut", "Cannot create texture"));
    }

    DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_1D, _id));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));

    GLenum format = GL_RGBA;

    if (djvPixel::F16 == djvPixel::type(_info.pixel))
    {
        format = GL_RGBA16F;
    }
    else if (djvPixel::F32 == djvPixel::type(_info.pixel))
    {
        format = GL_RGBA32F;
    }

    DJV_DEBUG_OPEN_GL(
        glTexImage1D(
            GL_TEXTURE_1D,
            0,
            format,
            _size,
            0,
            djvOpenGlUtil::format(_info.pixel, _info.bgr),
            djvOpenGlUtil::type(_info.pixel),
            0));
}
Пример #5
0
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 : &image;
    
    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();
}
Пример #6
0
void djvGlslTestOffscreen::init() throw (djvError)
{
    if (_id)
        return;

    //DJV_DEBUG("djvGlslTestOffscreen::init");

    DJV_DEBUG_OPEN_GL(glGenFramebuffers(1, &_id));

    if (! _id)
        throw djvError("glGenFramebuffers");
}
Пример #7
0
void djvWglContext::unbind()
{
#   if defined(DJV_WINDOWS)

    if (! wglMakeCurrent(_p->device, 0))
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_UNBIND_CONTEXT].arg(int(GetLastError())));
    }

#   endif // DJV_WINDOWS
}
Пример #8
0
djvWglContext::djvWglContext(djvCoreContext * context) throw (djvError) :
    djvOpenGlContext(context),
    _p(new djvWglContextPrivate)
{
#   if defined(DJV_WINDOWS)

    //DJV_DEBUG("djvWglContext::djvWglContext");

    // Create a dummy window and OpenGL context for glewInit.
    // According to the docs, glewInit can be called just once per-process?

    DJV_LOG(context->debugLog(), "djvWglContext", "Creating dummy window...");

    HINSTANCE hinstance = GetModuleHandle(0);

    if (! hinstance)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_MODULE_HANDLE].arg(int(GetLastError())));
    }

    static const char name [] = "djv";
    WNDCLASS wc;
    if (! GetClassInfo(hinstance, name, &wc))
    {
        wc.style = CS_OWNDC;
        //wc.lpfnWndProc = (WNDPROC)MainWndProc;
        wc.lpfnWndProc = DefWindowProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hinstance;
        wc.hIcon = LoadIcon(0, IDI_APPLICATION);
        wc.hCursor = LoadCursor(0, IDC_ARROW);
        wc.hbrBackground = 0;
        wc.lpszMenuName = 0;
        wc.lpszClassName = name;

        if (! RegisterClass(&wc))
        {
            throw djvError(
                "djvWglContext",
                errorLabels()[ERROR_REGISTER_CLASS].arg(int(GetLastError())));
        }
    }

    _p->id = CreateWindow(name, 0, 0, 0, 0, 0, 0, 0, 0, hinstance, 0);

    if (! _p->id)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_CREATE_WINDOW].arg(int(GetLastError())));
    }

    _p->device = GetDC(_p->id);

    if (! _p->device)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_GET_DC].arg(int(GetLastError())));
    }

    PIXELFORMATDESCRIPTOR pixelFormatInfo;

    const int pixelFormatCount = DescribePixelFormat(_p->device, 0, 0, 0);

    //DJV_DEBUG_PRINT("pixel format count = " << pixelFormatCount);

    DJV_LOG(context->debugLog(), "djvWglContext",
            QString("Pixel format count: %1").arg(pixelFormatCount));

    for (int i = 1; i < pixelFormatCount; ++i)
    {
        DescribePixelFormat(
            _p->device,
            i,
            sizeof(PIXELFORMATDESCRIPTOR),
            &pixelFormatInfo);

        //DJV_DEBUG_PRINT("  id " << i << ": " <<
        //    ((PFD_SUPPORT_OPENGL & pixelFormatInfo.dwFlags) ? "gl " : "") <<
        //    ((PFD_GENERIC_FORMAT & pixelFormatInfo.dwFlags) ? "" : "accel ") <<
        //    ((PFD_TYPE_RGBA == pixelFormatInfo.iPixelType) ? "rgba " : "") <<
        //    "depth = " << pixelFormatInfo.cColorBits << "/" <<
        //    pixelFormatInfo.cRedBits << "/" <<
        //    pixelFormatInfo.cGreenBits << "/" <<
        //    pixelFormatInfo.cBlueBits << "/" <<
        //    pixelFormatInfo.cAlphaBits << " ");

        QStringList tmp;
        if (PFD_SUPPORT_OPENGL & pixelFormatInfo.dwFlags)
            tmp += "gl";
        if (! (PFD_GENERIC_FORMAT & pixelFormatInfo.dwFlags))
            tmp += "accel";
        if (PFD_TYPE_RGBA == pixelFormatInfo.iPixelType)
            tmp += "rgba";

        DJV_LOG(context->debugLog(), "djvWglContext",
                QString("Pixel format %1: %2 %3/%4/%5/%6/%7").
                arg(i).
                arg(tmp.join(" ")).
                arg(pixelFormatInfo.cColorBits).
                arg(pixelFormatInfo.cRedBits).
                arg(pixelFormatInfo.cGreenBits).
                arg(pixelFormatInfo.cBlueBits).
                arg(pixelFormatInfo.cAlphaBits));
    }

    PIXELFORMATDESCRIPTOR pixelFormat =
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
        PFD_TYPE_RGBA,
        32,
        0, 0, 0, 0, 0, 0,
        0,
        0,
        0,
        0, 0, 0, 0,
        0,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0
    };

    int pixelFormatId = ChoosePixelFormat(_p->device, &pixelFormat);

    //DJV_DEBUG_PRINT("pixel format = " << pixelFormatId);

    DJV_LOG(context->debugLog(), "djvWglContext",
            QString("Chosen pixel format: %1").arg(pixelFormatId));

    if (! pixelFormatId)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_GET_PIXEL_FORMAT].arg(int(GetLastError())));
    }

    if (! SetPixelFormat(_p->device, pixelFormatId, &pixelFormat))
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_SET_PIXEL_FORMAT].arg(int(GetLastError())));
    }

    // Create OpengGL context.

    DJV_LOG(context->debugLog(), "djvWglContext", "Creating OpenGL context...");

    _p->context = wglCreateContext(_p->device);

    if (! _p->context)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_CREATE_CONTEXT].arg(int(GetLastError())));
    }

    if (! wglMakeCurrent(_p->device, _p->context))
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_BIND_CONTEXT].arg(int(GetLastError())));
    }

    // Initialize GLEW.

    DJV_LOG(context->debugLog(), "djvWglContext", "Initializing GLEW...");

    GLenum err = glewInit();

    if (err != GLEW_OK)
    {
        throw djvError(
            "djvWglContext",
            errorLabels()[ERROR_INIT_GLEW].arg((char *)glewGetErrorString(err)));
    }

    setVendor(QString((const char *)glGetString(GL_VENDOR)));
    setRenderer(QString((const char *)glGetString(GL_RENDERER)));
    setVersion(QString((const char *)glGetString(GL_VERSION)));

    //DJV_DEBUG_PRINT("OpenGL vendor string = " << vendor());
    //DJV_DEBUG_PRINT("OpenGL renderer string = " << renderer());
    //DJV_DEBUG_PRINT("OpenGL version string = " << version());
    //DJV_DEBUG_PRINT("OpenGL extensions = " <<
    //    (const char *)glGetString(GL_EXTENSIONS));
    //DJV_DEBUG_PRINT("glu version = " <<
    //    (const char *)gluGetString(GLU_VERSION));
    //DJV_DEBUG_PRINT("glu extensions = " <<
    //    (const char *)gluGetString(GLU_EXTENSIONS));

    DJV_LOG(context->debugLog(), "djvWglContext",
            QString("GL vendor: \"%1\"").arg(vendor()));
    DJV_LOG(context->debugLog(), "djvWglContext",
            QString("GL renderer: \"%1\"").arg(renderer()));
    DJV_LOG(context->debugLog(), "djvWglContext",
            QString("GL version: \"%1\"").arg(version()));

#   endif // DJV_WINDOWS
}
Пример #9
0
void djvLutPlugin::kodakOpen(djvFileIo & io, djvPixelDataInfo & info, TYPE type)
    throw (djvError)
{
    //DJV_DEBUG("djvLutPlugin::kodakOpen");

    // Header.

    const quint64 pos = io.pos();
    QString header;
    qint8 c = 0;
    bool comment = false;

    while (1)
    {
        try
        {
            io.get8(&c);
        }
        catch (const djvError &)
        {
            break;
        }

        if ('#' == c)
        {
            comment = true;
        }

        else if ('\n' == c)
        {
            if (comment)
            {
                comment = false;
            }
            else
            {
                break;
            }
        }
        else
        {
            if (! comment)
            {
                header += c;
            }
        }
    }

    //DJV_DEBUG_PRINT("header = " << header);

    const QStringList split = header.split(
        QRegExp("\\s"),
        QString::SkipEmptyParts);

    //DJV_DEBUG_PRINT("split = " << split.join("|"));

    const int channels = split.count();

    //DJV_DEBUG_PRINT("channels = " << channels);

    int size = 1;

    while (1)
    {
        try
        {
            io.get8(&c);
        }
        catch (const djvError &)
        {
            break;
        }

        if ('\n' == c)
        {
            ++size;
        }
    }

    io.setPos(pos);

    //DJV_DEBUG_PRINT("size = " << size);

    // Information.

    info.size = djvVector2i(size, 1);

    int bitDepth = 0;

    switch (type)
    {
        case TYPE_AUTO: bitDepth = _bitDepth(io); break;
        case TYPE_U8:   bitDepth = 8;             break;
        case TYPE_U10:  bitDepth = 10;            break;
        case TYPE_U16:  bitDepth = 16;            break;

        default: break;
    }

    //DJV_DEBUG_PRINT("bit depth = " << bitDepth);

    if (! djvPixel::pixel(channels, bitDepth, djvPixel::INTEGER, info.pixel))
    {
        throw djvError(
            djvLutPlugin::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED].
            arg(io.fileName()));
    }
}
Пример #10
0
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 : &image;
    
    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);
}
Пример #11
0
void djvFFmpegSave::open(const djvFileInfo & fileInfo, const djvImageIoInfo & info)
    throw (djvError)
{
    //DJV_DEBUG("djvFFmpegSave::open");
    //DJV_DEBUG_PRINT("fileInfo = " << fileInfo);
    //DJV_DEBUG_PRINT("info = " << info);
    
    close();
    
    _frame = 0;
        
    // Open the file.
    
    djvPixel::PIXEL pixel         = static_cast<djvPixel::PIXEL>(0);
    bool            bgr           = false;
    
    QString         avFormatName;
    AVCodecID       avCodecId     = static_cast<AVCodecID>(0);
    AVPixelFormat   avPixel       = static_cast<AVPixelFormat>(0);
    double          avQScale      = -1.0;
    
    _avFrameRgbPixel = static_cast<AVPixelFormat>(0);

    djvFFmpeg::Dictionary dictionary;
    QString               value;

    switch (_options.format)
    {
        /*case djvFFmpeg::H264:

            pixel            = djvPixel::RGBA_U8;
        
            avFormatName     = "mov";
            avCodecId        = AV_CODEC_ID_H264;
            
            switch (_options.quality)
            {
                case djvFFmpeg::LOW:    value = "fast";   break;
                case djvFFmpeg::MEDIUM: value = "medium"; break;
                case djvFFmpeg::HIGH:   value = "slow";   break;

                default: break;
            }

            av_dict_set(
                dictionary(),
                "preset",
                value.toLatin1().data(),
                0);

            break;*/
        
        case djvFFmpeg::MPEG4:

            pixel            = djvPixel::RGBA_U8;
            bgr              = info.bgr;

            avFormatName     = "mp4";
            avCodecId        = AV_CODEC_ID_MPEG4;
            avPixel          = AV_PIX_FMT_YUV420P;
            _avFrameRgbPixel = bgr ? AV_PIX_FMT_BGRA : AV_PIX_FMT_RGBA;

            switch (_options.quality)
            {
                case djvFFmpeg::LOW:    avQScale = 9.0; break;
                case djvFFmpeg::MEDIUM: avQScale = 3.0; break;
                case djvFFmpeg::HIGH:   avQScale = 1.0; break;

                default: break;
            }

            break;
        
        case djvFFmpeg::PRO_RES:

            pixel            = djvPixel::RGB_U16;
            bgr              = info.bgr;

            avFormatName     = "mov";
            avCodecId        = AV_CODEC_ID_PRORES;
            avPixel          = AV_PIX_FMT_YUV422P10;
            _avFrameRgbPixel = bgr ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_BGR48;
         
            switch (_options.quality)
            {
                case djvFFmpeg::LOW:    value = "1"; break;
                case djvFFmpeg::MEDIUM: value = "2"; break;
                case djvFFmpeg::HIGH:   value = "3"; break;

                default: break;
            }

            av_dict_set(
                dictionary(),
                "profile",
                value.toLatin1().data(),
                0);

            break;
        
        case djvFFmpeg::MJPEG:

            pixel            = djvPixel::RGBA_U8;
            bgr              = info.bgr;

            avFormatName     = "mov";
            avCodecId        = AV_CODEC_ID_MJPEG;
            avPixel          = AV_PIX_FMT_YUVJ422P;
            _avFrameRgbPixel = bgr ? AV_PIX_FMT_BGRA : AV_PIX_FMT_RGBA;

            switch (_options.quality)
            {
                case djvFFmpeg::LOW:    avQScale = 9.0; break;
                case djvFFmpeg::MEDIUM: avQScale = 3.0; break;
                case djvFFmpeg::HIGH:   avQScale = 1.0; break;

                default: break;
            }

            break;
        
        default: break;
    }
    
    //DJV_DEBUG_PRINT("pixel = " << pixel);

    //DJV_DEBUGBUG_PRINT("av format name = " << avFormatName);
    //DJV_DEBUGBUG_PRINT("av codec id = " << avCodecId);
    //DJV_DEBUGBUG_PRINT("av pixel = " << avPixel);
    //DJV_DEBUGBUG_PRINT("av rgb pixel = " << _avFrameRgbPixel);
    //DJV_DEBUGBUG_PRINT("av qscale = " << avQScale);
    
    AVOutputFormat * avFormat = av_guess_format(
        avFormatName.toLatin1().data(),
        0, //fileInfo.fileName().toLatin1().data(),
        0);
    
    if (! avFormat)
    {
        throw djvError(
            djvFFmpeg::staticName,
            qApp->translate("djvFFmpegSave", "Cannot find format: %1").
                arg(djvFFmpeg::formatLabels()[_options.format]));
    }
    
    //DJV_DEBUGBUG_PRINT("av format extensions = " << avFormat->extensions);
    
    _avFormatContext = avformat_alloc_context();
    _avFormatContext->oformat = avFormat;

    AVCodec * avCodec = avcodec_find_encoder(avCodecId);

    if (! avCodec)
    {
        throw djvError(
            djvFFmpeg::staticName,
            qApp->translate("djvFFmpegSave", "Cannot find encoder: %1").
                arg(djvFFmpeg::formatLabels()[_options.format]));
    }

    AVCodecContext * avCodecContext = avcodec_alloc_context3(avCodec);
    
    avcodec_get_context_defaults3(avCodecContext, avCodec);
    
    //DJV_DEBUGBUG_PRINT("default bit rate = " << avCodecContext->bit_rate);
    //DJV_DEBUGBUG_PRINT("default gop = " << avCodecContext->gop_size);
    
    avCodecContext->pix_fmt       = avPixel;
    avCodecContext->width         = info.size.x;
    avCodecContext->height        = info.size.y;
    avCodecContext->time_base.den = info.sequence.speed.scale();
    avCodecContext->time_base.num = info.sequence.speed.duration();
    
    if (avFormat->flags & AVFMT_GLOBALHEADER)
        avCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;

    if (avQScale >= 0.0)
    {
        avCodecContext->flags |= CODEC_FLAG_QSCALE;
        avCodecContext->global_quality = FF_QP2LAMBDA * avQScale;
    }
    
    int r = avcodec_open2(avCodecContext, avCodec, dictionary());
    
    if (r < 0)
    {
        throw djvError(
            djvFFmpeg::staticName,
            djvFFmpeg::toString(r));
    }

    _avStream = avformat_new_stream(_avFormatContext, avCodecContext->codec);

    if (! _avStream)
    {
        throw djvError(
            djvFFmpeg::staticName,
            qApp->translate("djvFFmpegSave", "Cannot create stream"));
    }
    
    _avStream->codec         = avCodecContext;
    _avStream->time_base.den = info.sequence.speed.scale();
    _avStream->time_base.num = info.sequence.speed.duration();
    
    r = avio_open2(
        &_avIoContext,
        fileInfo.fileName().toLatin1().data(),
        AVIO_FLAG_READ_WRITE,
        0,
        0);
    
    if (r < 0)
    {
        throw djvError(
            djvFFmpeg::staticName,
            djvFFmpeg::toString(r));
    }
    
    _avFormatContext->pb = _avIoContext;

    r = avformat_write_header(_avFormatContext, 0);
    
    if (r < 0)
    {
        throw djvError(
            djvFFmpeg::staticName,
            djvFFmpeg::toString(r));
    }
    
    _info          = djvPixelDataInfo();
    _info.fileName = fileInfo;
    _info.size     = info.size;
    _info.pixel    = pixel;
    _info.bgr      = info.bgr;

    // Initialize the buffers.
    
    _image.set(_info);
    
    _avFrame         = av_frame_alloc();
    _avFrame->width  = info.size.x;
    _avFrame->height = info.size.y;
    _avFrame->format = avCodecContext->pix_fmt;

    _avFrameBuf = (uint8_t *)av_malloc(
        avpicture_get_size(
            avCodecContext->pix_fmt,
            avCodecContext->width,
            avCodecContext->height));

    avpicture_fill(
        (AVPicture *)_avFrame,
        _avFrameBuf,
        avCodecContext->pix_fmt,
        avCodecContext->width,
        avCodecContext->height);

    _avFrameRgb = av_frame_alloc();
    
    // Initialize the software scaler.

    _swsContext = sws_getContext(
        info.size.x,
        info.size.y,
        _avFrameRgbPixel,
        avCodecContext->width,
        avCodecContext->height,
        avCodecContext->pix_fmt,
        SWS_BILINEAR,
        0,
        0,
        0);

    if (! _swsContext)
    {
        throw djvError(
            djvFFmpeg::staticName,
            qApp->translate("djvFFmpegSave", "Cannot create software scaler"));
    }
}
Пример #12
0
void djvFFmpegSave::close() throw (djvError)
{
    //DJV_DEBUG("djvFFmpegSave::close");
    
    djvError error;
    
    int r = 0;
    
    if (_avFormatContext)
    {
        r = av_interleaved_write_frame(_avFormatContext, 0);
        
        if (r < 0)
        {
            throw djvError(
                djvFFmpeg::staticName,
                djvFFmpeg::toString(r));
        }
    
        //DJV_DEBUG_PRINT("frames = " <<
        //    static_cast<qint64>(_avStream->nb_frames));
        //DJV_DEBUG_PRINT("write trailer");
        
        r = av_write_trailer(_avFormatContext);
        
        if (r < 0)
        {
            throw djvError(
                djvFFmpeg::staticName,
                djvFFmpeg::toString(r));
        }
    }

    if (_swsContext)
    {
        sws_freeContext(_swsContext);
        
        _swsContext = 0;
    }

    if (_avFrameRgb)
    {
        av_frame_free(&_avFrameRgb);
        
        _avFrameRgb = 0;
    }

    if (_avFrameBuf)
    {
        av_free(_avFrameBuf);

        _avFrameBuf = 0;
    }

    if (_avFrame)
    {
        av_frame_free(&_avFrame);
        
        _avFrame = 0;
    }

    if (_avIoContext)
    {
        avio_close(_avIoContext);
        
        _avIoContext = 0;
    }

    if (_avFormatContext)
    {
        avformat_free_context(_avFormatContext);
        
        _avFormatContext = 0;
    }
    
    if (error.count())
    {
        throw error;
    }
}
Пример #13
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));
    }
}
Пример #14
0
void djvPngLoad::_open(const QString & in, djvImageIoInfo & info)
    throw (djvError)
{
    //DJV_DEBUG("djvPngLoad::_open");
    //DJV_DEBUG_PRINT("in = " << in);

    close();

    // Initialize libpng.

    _png = png_create_read_struct(
        PNG_LIBPNG_VER_STRING,
        &_pngError,
        djvPngError,
        djvPngWarning);

    if (! _png)
    {
        throw djvError(
            djvPng::staticName,
            _pngError.msg);
    }

    // Open the file.

#if defined(DJV_WINDOWS)

    ::fopen_s(&_f, in.toLatin1().data(), "rb");

#else

    _f = ::fopen(in.toLatin1().data(), "rb");

#endif

    if (! _f)
    {
        throw djvError(
            djvPng::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_OPEN]);
    }

    if (! pngOpen(_f, _png, &_pngInfo, &_pngInfoEnd))
    {
        throw djvError(
            djvPng::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_OPEN]);
    }

    // Get file information.

    info.fileName = in;

    info.size = djvVector2i(
        png_get_image_width(_png, _pngInfo),
        png_get_image_height(_png, _pngInfo));

    int channels = png_get_channels(_png, _pngInfo);

    if (png_get_color_type(_png, _pngInfo) == PNG_COLOR_TYPE_PALETTE)
    {
        channels = 3;
    }

    if (png_get_valid(_png, _pngInfo, PNG_INFO_tRNS))
    {
        ++channels;
    }

    //DJV_DEBUG_PRINT("channels = " << channels);

    int bitDepth = png_get_bit_depth(_png, _pngInfo);

    if (bitDepth < 8)
    {
        bitDepth = 8;
    }

    //DJV_DEBUG_PRINT("bit depth = " << bitDepth);

    if (! djvPixel::pixel(channels, bitDepth, djvPixel::INTEGER, info.pixel))
    {
        throw djvError(
            djvPng::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    // Set the endian.
    
    if (bitDepth >= 16 && djvMemory::LSB == djvMemory::endian())
    {
        png_set_swap(_png);
    }
}
Пример #15
0
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 : &image;

    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);
}
Пример #16
0
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);
}
Пример #17
0
void djvOpenGlImageTexture::init(
    const djvPixelDataInfo & info,
    GLenum                   min,
    GLenum                   mag) throw (djvError)
{
    if (info == _info && min == _min && mag == _mag)
        return;

    del();

    //DJV_DEBUG("djvOpenGlImageTexture::init");
    //DJV_DEBUG_PRINT("info = " << info);

    _info = info;
    _min  = min;
    _mag  = mag;

    DJV_DEBUG_OPEN_GL(glGenTextures(1, &_id));

    //DJV_DEBUG_PRINT("id = " << int(_id));

    if (! _id)
    {
        throw djvError(
            "djvOpenGlImageTexture",
            djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_TEXTURE]);
    }

    DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, _id));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min));
    DJV_DEBUG_OPEN_GL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag));

    GLenum format = GL_RGBA;

    if (djvPixel::F16 == djvPixel::type(_info.pixel))
    {
        format = GL_RGBA16F;
    }
    else if (djvPixel::F32 == djvPixel::type(_info.pixel))
    {
        format = GL_RGBA32F;
    }

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        format,
        _info.size.x,
        _info.size.y,
        0,
        djvOpenGlUtil::format(_info.pixel, _info.bgr),
        djvOpenGlUtil::type(_info.pixel),
        0);
    
    GLenum error = glGetError();
    
#if ! defined(DJV_OSX)

    //! \todo On OS X this error is triggered the first time djv_view is
    //! started, though it doesn't actually seem to be a problem? If we
    //! throw here the image is not displayed (start djv_view from the
    //! command line with an image), but if we igore the error the image is
    //! displayed OK? Is this related to the "invalid drawable" message we
    //! are also getting on start up?
    
    if (error != GL_NO_ERROR)
    {
        throw djvError(
            "djvOpenGlImageTexture",
            djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_TEXTURE2].
            arg((char *)gluErrorString(error)));
    }
    
#endif // DJV_OSX
}
Пример #18
0
void djvRlaLoad::_open(const QString & in, djvImageIoInfo & info, djvFileIo & io)
    throw (djvError)
{
    //DJV_DEBUG("djvRlaLoad::_open");
    //DJV_DEBUG_PRINT("in = " << in);

    // Open the file.

    io.setEndian(djvMemory::endian() != djvMemory::MSB);

    io.open(in, djvFileIo::READ);

    // Read the header.

    Header header;

    //DJV_DEBUG_PRINT("header size = " << static_cast<int>(sizeof(Header)));

    io.get(&header, sizeof(Header));

    if (io.endian())
    {
        endian(&header);
    }

    debug(header);

    const int w = header.active[1] - header.active[0] + 1;
    const int h = header.active[3] - header.active[2] + 1;

    // Read the scanline table.

    _rleOffset.setSize(h);
    
    io.get32(_rleOffset(), h);

    // Get file information.

    const djvVector2i size(w, h);
    
    djvPixel::PIXEL pixel = static_cast<djvPixel::PIXEL>(0);

    if (header.matteChannels > 1)
    {
        throw djvError(
            djvRla::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    if (header.matteChannelType != header.colorChannelType)
    {
        throw djvError(
            djvRla::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    if (header.matteBitDepth != header.colorBitDepth)
    {
        throw djvError(
            djvRla::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    if (! djvPixel::pixel(
        header.colorChannels + header.matteChannels,
        header.colorBitDepth,
        3 == header.colorChannelType ? djvPixel::FLOAT : djvPixel::INTEGER,
        pixel))
    {
        throw djvError(
            djvRla::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    if (header.field)
    {
        throw djvError(
            djvRla::staticName,
            djvImageIo::errorLabels()[djvImageIo::ERROR_UNSUPPORTED]);
    }

    info = djvPixelDataInfo(in, size, pixel);
}