void djvFileBrowserModel::imageLoadCallback() { //DJV_DEBUG("djvFileBrowserModel::imageLoadCallback"); QFutureWatcher<Image> * watcher = dynamic_cast<QFutureWatcher<Image> *>(sender()); const QFuture<Image> & future = watcher->future(); const Image & image = future.result(); //DJV_DEBUG_PRINT("image = " << image.image); if (image.row < _p->items.count() && image.item == &_p->items[image.row] && image.valid) { QPixmap thumbnail; try { // Scale the image. djvImage tmp(djvPixelDataInfo( image.item->thumbnailSize(), image.image.pixel())); djvOpenGlImageOptions options; options.xform.scale = djvVector2f(tmp.size()) / (djvVector2f(image.image.size() * djvPixelDataUtil::proxyScale(image.image.info().proxy))); options.colorProfile = image.image.colorProfile; if (djvFileBrowserModel::THUMBNAILS_HIGH == _p->thumbnails) { options.filter = djvOpenGlImageFilter::filterHighQuality(); } djvOpenGlImage::copy(image.image, tmp, options); thumbnail = djvPixelDataUtil::toQt(tmp); } catch (const djvError & error) { DJV_LOG("djvFileBrowserModel", djvErrorUtil::format(error).join("\n")); } _p->items[image.row].setThumbnail(thumbnail); const QModelIndex index = this->index(image.row, 0); Q_EMIT dataChanged(index, index); } watcher->deleteLater(); }
void djvVectorUtilTest::convert() { DJV_DEBUG("djvVectorUtilTest::convert"); djvVector2i v2i = djvVectorUtil::convert<double, int, 2>(djvVector2f(1.0, 2.0)); DJV_ASSERT(v2i == djvVector2i(1, 2)); v2i = djvVectorUtil::ceil<double, int, 2>(djvVector2f(0.5, 0.5)); DJV_ASSERT(v2i == djvVector2i(1, 1)); v2i = djvVectorUtil::floor<double, int, 2>(djvVector2f(0.5, 0.5)); DJV_ASSERT(v2i == djvVector2i(0, 0)); DJV_ASSERT((QStringList() << "1" << "2") == djvStringUtil::label(djvVector2i(1, 2))); }
void djvImageView::viewFit() { if (! _p->data) return; //DJV_DEBUG("djvImageView::viewFit"); const djvBox2i geom(width(), height()); //DJV_DEBUG_PRINT("geom = " << geom.size); const djvBox2f bbox = this->bbox(djvVector2i(), 1.0); //DJV_DEBUG_PRINT("bbox = " << bbox); const double zoom = djvVectorUtil::isSizeValid(bbox.size) ? djvMath::min(geom.w / bbox.size.x, geom.h / bbox.size.y) : 1.0; //DJV_DEBUG_PRINT("zoom = " << zoom); djvVector2i pos = djvVector2f(geom.size) / 2.0 - bbox.size * zoom / 2.0 - this->bbox(djvVector2i(), zoom).position; //DJV_DEBUG_PRINT("pos = " << pos); setViewPosZoom(pos, zoom); //DJV_DEBUG_PRINT("fit"); _p->viewFit = true; }
void djvGlslTestUtil::quad(const djvPixelDataInfo & in) { double u [] = { 0, 0 }, v [] = { 0, 0 }; u[! in.mirror.x] = in.size.x; v[! in.mirror.y] = in.size.y; const djvVector2f uv[] = { djvVector2f(u[0], v[0]), djvVector2f(u[0], v[1]), djvVector2f(u[1], v[1]), djvVector2f(u[1], v[0]) }; glBegin(GL_QUADS); djvOpenGlUtil::drawBox(djvBox2i(in.size), uv); glEnd(); }
djvVector2i djvWindowUtil::resize(const djvVector2i & size, double maxPercent) { const QSize qSize = qApp->desktop()->availableGeometry().size(); return djvVectorUtil::min( size, djvVector2i(djvVector2f(qSize.width(), qSize.height()) * maxPercent)); }
void djvImageView::setViewZoom(double zoom, const djvVector2i & focus) { //DJV_DEBUG("djvImageView::setViewZoom"); //DJV_DEBUG_PRINT("zoom = " << zoom); //DJV_DEBUG_PRINT("focus = " << focus); setViewPosZoom( focus + djvVector2i(djvVector2f(_p->viewPos - focus) * (zoom / _p->viewZoom)), zoom); }
void djvVectorUtilTest::normalize() { DJV_DEBUG("djvVectorUtilTest::normalize"); DJV_ASSERT(djvVectorUtil::normalize(djvVector2f(0.0, 2.0)) == djvVector2f(0.0, 1.0)); }
void djvVectorUtilTest::dot() { DJV_DEBUG("djvVectorUtilTest::dot"); DJV_ASSERT(djvVectorUtil::dot(djvVector2f(1.0, 0.0), djvVector2f(0.0, 1.0)) == 0.0); }
void djvViewMagnifyTool::pixelDataUpdate() { //DJV_DEBUG("djvViewMagnifyTool::pixelDataUpdate"); djvSignalBlocker signalBlocker(QObjectList() << _p->widget); djvPixelData tmp(djvPixelDataInfo( _p->widget->width(), _p->widget->height(), djvPixel::RGB_U8)); if (const djvPixelData * data = viewWidget()->data()) { //DJV_DEBUG_PRINT("data = " << *data); const double zoom = djvMath::pow(2, _p->zoom); djvVector2i pick = djvVectorUtil::floor<double, int>( djvVector2f(_p->pick - viewWidget()->viewPos()) * zoom - djvVector2f(tmp.info().size) / 2.0); //DJV_DEBUG_PRINT("zoom = " << zoom); //DJV_DEBUG_PRINT("pick = " << pick); try { viewWidget()->makeCurrent(); if (! _p->magnifyBuffer || _p->magnifyBuffer->info() != tmp.info()) { _p->magnifyBuffer.reset(new djvOpenGlOffscreenBuffer(tmp.info())); } djvOpenGlImageOptions options = viewWidget()->options(); options.xform.position -= pick; options.xform.scale *= zoom * viewWidget()->viewZoom(); if (! _p->colorProfile) { options.colorProfile = djvColorProfile(); } if (! _p->displayProfile) { options.displayProfile = djvViewDisplayProfile(); } djvOpenGlImage::copy( *data, tmp, options, &_p->magnifyState, _p->magnifyBuffer.data()); _p->widget->setPixmap( djvPixmapUtil::toQt( tmp, djvOpenGlImageOptions(), &_p->convertState, _p->convertBuffer.data())); } catch (djvError error) { error.add( djvViewUtil::errorLabels()[djvViewUtil::ERROR_MAGNIFY]); context()->printError(error); } } //_p->widget->setPixelData(tmp); _p->pixelDataInit = false; }
void djvOpenGlTest::members() { DJV_DEBUG("djvOpenGlTest::members"); djvImageContext context; QScopedPointer<djvOpenGlContext> openGlContext( context.openGlContextFactory()->create()); djvOpenGlContextScope contextScope(openGlContext.data()); QScopedPointer<djvOpenGlOffscreenBuffer> buffer( new djvOpenGlOffscreenBuffer(djvPixelDataInfo(100, 100, djvPixel::RGBA_U8))); djvOpenGlOffscreenBufferScope bufferScope(buffer.data()); DJV_DEBUG_PRINT("buffer = " << buffer->info()); DJV_DEBUG_PRINT("buffer id = " << buffer->id()); DJV_DEBUG_PRINT("buffer texture = " << buffer->texture()); { djvOpenGlUtil::ortho(djvVector2i(100, 100)); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); djvOpenGlUtil::color(djvColor(0.5)); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); djvOpenGlUtil::drawBox(djvBox2i(25, 25, 50, 50)); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); djvOpenGlUtil::drawBox(djvBox2f(50.0, 50.0, 50.0, 50.0)); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); djvVector2f uv[4] = { djvVector2f(0.0, 0.0), djvVector2f(0.1, 0.0), djvVector2f(0.1, 1.0), djvVector2f(0.0, 1.0) }; djvOpenGlUtil::drawBox(djvBox2i(25, 25, 50, 50), uv); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); djvOpenGlUtil::drawBox(djvBox2f(50.0, 50.0, 50.0, 50.0), uv); DJV_ASSERT(GL_NO_ERROR == ::glGetError()); } { for (int i = 0; i < djvPixel::PIXEL_COUNT; ++i) { DJV_ASSERT(djvOpenGlUtil::format(static_cast<djvPixel::PIXEL>(i))); DJV_ASSERT(djvOpenGlUtil::type(static_cast<djvPixel::PIXEL>(i))); } } }
void djvOpenGlImage::draw( const djvPixelData & data, const djvOpenGlImageOptions & options, djvOpenGlImageState * state) throw (djvError) { //DJV_DEBUG("djvOpenGlImage::draw"); //DJV_DEBUG_PRINT("data = " << data); //DJV_DEBUG_PRINT("color profile = " << options.colorProfile); RestoreState restoreState; djvOpenGlImageState defaultState; if (! state) { state = &defaultState; } const djvPixelDataInfo & info = data.info(); const int proxyScale = options.proxyScale ? djvPixelDataUtil::proxyScale(info.proxy) : 1; const djvVector2i scale = djvVectorUtil::ceil<double, int>( options.xform.scale * djvVector2f(info.size * proxyScale)); const djvVector2i scaleTmp(scale.x, data.h()); //DJV_DEBUG_PRINT("scale = " << scale); //DJV_DEBUG_PRINT("scale tmp = " << scaleTmp); // Initialize. const djvOpenGlImageFilter::FILTER filter = info.size == scale ? djvOpenGlImageFilter::NEAREST : (djvVectorUtil::area(scale) < djvVectorUtil::area(info.size) ? options.filter.min : options.filter.mag); //DJV_DEBUG_PRINT("filter min = " << options.filter.min); //DJV_DEBUG_PRINT("filter mag = " << options.filter.mag); //DJV_DEBUG_PRINT("filter = " << filter); if (! state->_init || state->_info != info || state->_options != options) { switch (filter) { case djvOpenGlImageFilter::NEAREST: case djvOpenGlImageFilter::LINEAR: { //DJV_DEBUG_PRINT("init single pass"); state->_texture->init( data.info(), djvOpenGlImageFilter::toGl(filter), djvOpenGlImageFilter::toGl(filter)); state->_shader->init( sourceVertex, sourceFragment( options.colorProfile.type, options.displayProfile, options.channel, false, 0, false)); } break; case djvOpenGlImageFilter::BOX: case djvOpenGlImageFilter::TRIANGLE: case djvOpenGlImageFilter::BELL: case djvOpenGlImageFilter::BSPLINE: case djvOpenGlImageFilter::LANCZOS3: case djvOpenGlImageFilter::CUBIC: case djvOpenGlImageFilter::MITCHELL: { //DJV_DEBUG_PRINT("init two pass"); state->_texture->init( data.info(), GL_NEAREST, GL_NEAREST); // Initialize horizontal pass. djvPixelData contrib; scaleContrib( data.w(), scale.x, filter, contrib); state->_scaleXContrib->init( contrib, GL_NEAREST, GL_NEAREST); state->_scaleXShader->init( sourceVertex, sourceFragment( options.colorProfile.type, djvOpenGlImageDisplayProfile(), static_cast<djvOpenGlImageOptions::CHANNEL>(0), true, contrib.h(), true)); // Initialize vertical pass. scaleContrib( data.h(), scale.y, filter, contrib); state->_scaleYContrib->init( contrib, GL_NEAREST, GL_NEAREST); state->_scaleYShader->init( sourceVertex, sourceFragment( static_cast<djvColorProfile::PROFILE>(0), options.displayProfile, options.channel, true, contrib.h(), false)); } break; default: break; } state->_init = true; state->_info = info; state->_options = options; } // Render. const djvPixelDataInfo::Mirror mirror( info.mirror.x ? (! options.xform.mirror.x) : options.xform.mirror.x, info.mirror.y ? (! options.xform.mirror.y) : options.xform.mirror.y); //DJV_DEBUG_PRINT("mirror = " << mirror.x << " " << mirror.y); switch (filter) { case djvOpenGlImageFilter::NEAREST: case djvOpenGlImageFilter::LINEAR: { //DJV_DEBUG_PRINT("draw single pass"); state->_shader->bind(); // Initialize color and display profiles. colorProfileInit( options, state->_shader->program(), *state->_lutColorProfile); displayProfileInit( options, state->_shader->program(), *state->_lutDisplayProfile); // Draw. activeTexture(GL_TEXTURE0); uniform1i(state->_shader->program(), "inTexture", 0); state->_texture->copy(data); state->_texture->bind(); DJV_DEBUG_OPEN_GL(glPushMatrix()); const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(options.xform); //DJV_DEBUG_PRINT("m = " << m); DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e)); quad(info.size, mirror, proxyScale); DJV_DEBUG_OPEN_GL(glPopMatrix()); } break; case djvOpenGlImageFilter::BOX: case djvOpenGlImageFilter::TRIANGLE: case djvOpenGlImageFilter::BELL: case djvOpenGlImageFilter::BSPLINE: case djvOpenGlImageFilter::LANCZOS3: case djvOpenGlImageFilter::CUBIC: case djvOpenGlImageFilter::MITCHELL: { //DJV_DEBUG_PRINT("draw two pass"); // Horizontal pass. djvOpenGlOffscreenBuffer buffer( djvPixelDataInfo(scaleTmp, data.pixel())); { djvOpenGlOffscreenBufferScope bufferScope(&buffer); state->_scaleXShader->bind(); colorProfileInit( options, state->_scaleXShader->program(), *state->_lutColorProfile); activeTexture(GL_TEXTURE0); uniform1i(state->_scaleXShader->program(), "inTexture", 0); state->_texture->copy(data); state->_texture->bind(); activeTexture(GL_TEXTURE1); uniform1i( state->_scaleXShader->program(), "inScaleContrib", 1); state->_scaleXContrib->bind(); glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); djvOpenGlUtil::ortho(scaleTmp); glViewport(0, 0, scaleTmp.x, scaleTmp.y); quad(scaleTmp, mirror); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } // Vertical pass. state->_scaleYShader->bind(); displayProfileInit( options, state->_scaleYShader->program(), *state->_lutDisplayProfile); activeTexture(GL_TEXTURE0); uniform1i(state->_scaleYShader->program(), "inTexture", 0); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, buffer.texture())); activeTexture(GL_TEXTURE1); uniform1i(state->_scaleYShader->program(), "inScaleContrib", 1); state->_scaleYContrib->bind(); djvOpenGlImageXform xform = options.xform; xform.scale = djvVector2f(1.0); const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(xform); DJV_DEBUG_OPEN_GL(glPushMatrix()); DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e)); quad(scale); DJV_DEBUG_OPEN_GL(glPopMatrix()); } break; default: break; } }
void djvImageView::viewCenter() { setViewPos(djvVector2f(width(), height()) / 2.0 - bbox().size / 2.0); }
void djvOpenGlImageTest::operators() { DJV_DEBUG("djvOpenGlImageTest::operators"); { djvOpenGlImageXform a, b; a.mirror = b.mirror = djvPixelDataInfo::Mirror(true, true); DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageXform()); } { djvOpenGlImageColor a, b; a.brightness = b.brightness = 2.0; DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageColor()); } { djvOpenGlImageLevels a, b; a.gamma = b.gamma = 2.2; DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageLevels()); } { djvOpenGlImageDisplayProfile a, b; a.softClip = b.softClip = 0.5; DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageDisplayProfile()); } { djvOpenGlImageFilter a, b; a.min = b.min = djvOpenGlImageFilter::BOX; DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageFilter()); } { djvOpenGlImageOptions a, b; a.channel = b.channel = djvOpenGlImageOptions::CHANNEL_RED; DJV_ASSERT(a == b); DJV_ASSERT(a != djvOpenGlImageOptions()); } { djvOpenGlImageXform a; a.mirror = djvPixelDataInfo::Mirror(true, true); a.position = djvVector2f(1.0, 2.0); a.scale = djvVector2f(3.0, 4.0); a.rotate = 5.0; QStringList tmp; tmp << a; djvOpenGlImageXform b; tmp >> b; DJV_ASSERT(a == b); } { djvOpenGlImageColor a; a.brightness = 1.0; a.contrast = 2.0; a.saturation = 3.0; QStringList tmp; tmp << a; djvOpenGlImageColor b; tmp >> b; DJV_ASSERT(a == b); } { djvOpenGlImageLevels a; a.inLow = 1.0; a.inHigh = 2.0; a.gamma = 3.0; a.outLow = 4.0; a.outHigh = 5.0; QStringList tmp; tmp << a; djvOpenGlImageLevels b; tmp >> b; DJV_ASSERT(a == b); } { DJV_DEBUG_PRINT(djvOpenGlImageFilter::BELL); DJV_DEBUG_PRINT(djvOpenGlImageOptions::CHANNEL_RED); } }