author | alwin <alwin> | 2004-04-14 12:39:03 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-04-14 12:39:03 (UTC) |
commit | 4f78995cbb47f78e68eb40d9a86a6a0dcdc576eb (patch) (side-by-side diff) | |
tree | 24f22c258d4fac1924c0be938dca7a5b52a5a3d4 | |
parent | 3ed50198400e432b308ca58178f562e2e256de0e (diff) | |
download | opie-4f78995cbb47f78e68eb40d9a86a6a0dcdc576eb.zip opie-4f78995cbb47f78e68eb40d9a86a6a0dcdc576eb.tar.gz opie-4f78995cbb47f78e68eb40d9a86a6a0dcdc576eb.tar.bz2 |
jpegs will be loaded scaled if needed for a faster preview loading
-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.cpp | 86 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.h | 3 |
2 files changed, 83 insertions, 6 deletions
diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.cpp b/noncore/graphics/opie-eye/gui/imagescrollview.cpp index 2f16d82..d034ee0 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.cpp +++ b/noncore/graphics/opie-eye/gui/imagescrollview.cpp @@ -1,169 +1,235 @@ #include "imagescrollview.h" #include <opie2/odebug.h> +#include <opie2/oapplication.h> +#include <opie2/owait.h> using namespace Opie::Core; #include <qimage.h> #include <qlayout.h> +#include <qpe/qcopenvelope_qws.h> ImageScrollView::ImageScrollView( QWidget* parent, const char* name, WFlags f ) :QScrollView(parent,name,f|Qt::WRepaintNoErase ),_image_data(),_original_data(),scale_to_fit(true), rotate_to_fit(true),show_zoomer(true),first_resize_done(false),m_lastName("") { init(); } ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale), rotate_to_fit(rfit),show_zoomer(true),first_resize_done(false),m_lastName("") { _original_data.convertDepth(QPixmap::defaultDepth()); _original_data.setAlphaBuffer(false); init(); } ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(),scale_to_fit(always_scale), rotate_to_fit(rfit),show_zoomer(true),first_resize_done(false),m_lastName("") { init(); setImage(img); } void ImageScrollView::setImage(const QImage&img) { _image_data = QImage(); _original_data=img; _original_data.convertDepth(QPixmap::defaultDepth()); _original_data.setAlphaBuffer(false); m_lastName = ""; + image_is_jpeg = false; + image_scaled_loaded = false; if (first_resize_done) { generateImage(); } } +void ImageScrollView::loadJpeg(bool interncall) +{ + if (m_lastName.isEmpty()) return; + QImageIO iio( m_lastName, 0l ); + QString param; + bool real_load = false; + if (scale_to_fit) { + if (!interncall) { + int wid, hei; + wid = QApplication::desktop()->width(); + hei = QApplication::desktop()->height(); + if (hei>wid) { + wid = hei; + } else { + hei = wid; + } + param = QString( "Fast Shrink( 7 ) Scale( %1, %2, ScaleFree)" ).arg( wid ).arg( hei ); + odebug << "Load jpeg scaled \"" << param << "\"" << oendl; + iio.setParameters(param.latin1()); + image_scaled_loaded = true; + real_load = true; + } + } else { + if (image_scaled_loaded||!interncall) { + odebug << "Load jpeg unscaled" << oendl; + real_load = true; + } + image_scaled_loaded = false; + } + if (real_load) { + { + QCopEnvelope( "QPE/System", "busy()" ); + } + _original_data = iio.read() ? iio.image() : QImage(); + { + QCopEnvelope env( "QPE/System", "notBusy(QString)" ); + env << "Image loaded"; + } + } +} + void ImageScrollView::setImage( const QString& path ) { odebug << "load new image " << oendl; if (m_lastName == path) return; m_lastName = path; - _original_data.load(path); - _original_data.convertDepth(QPixmap::defaultDepth()); - _original_data.setAlphaBuffer(false); + QString itype = QImage::imageFormat(m_lastName); + odebug << "Image type = " << itype << oendl; + if (itype == "JPEG") { + image_is_jpeg = true; + loadJpeg(); + } else { + { + QCopEnvelope( "QPE/System", "busy()" ); + } + image_is_jpeg = false; + _original_data.load(path); + _original_data.convertDepth(QPixmap::defaultDepth()); + _original_data.setAlphaBuffer(false); + { + QCopEnvelope env( "QPE/System", "notBusy(QString)" ); + env << "Image loaded"; + } + } _image_data = QImage(); if (first_resize_done) { generateImage(); } } /* should be called every time the QImage changed it content */ void ImageScrollView::init() { odebug << "init " << oendl; /* * create the zoomer * and connect ther various signals */ _zoomer = new Opie::MM::OImageZoomer( this, "The Zoomer" ); connect(_zoomer, SIGNAL( zoomAreaRel(int,int)), this, SLOT(scrollBy(int,int)) ); connect(this,SIGNAL(contentsMoving(int,int)), _zoomer, (SLOT(setVisiblePoint(int,int))) ); connect(this,SIGNAL(imageSizeChanged(const QSize&)), _zoomer, SLOT(setImageSize(const QSize&)) ); connect(this,SIGNAL(viewportSizeChanged(const QSize&)), _zoomer, SLOT(setViewPortSize(const QSize&)) ); viewport()->setBackgroundColor(white); setFocusPolicy(QWidget::StrongFocus); + image_scaled_loaded = false; + image_is_jpeg = false; if (first_resize_done) { last_rot = Rotate0; generateImage(); } else if (_original_data.size().isValid()) { if (image_fit_into(_original_data.size()) || !show_zoomer) _zoomer->hide(); resizeContents(_original_data.width(),_original_data.height()); } } void ImageScrollView::setAutoRotate(bool how) { /* to avoid double repaints */ if (rotate_to_fit != how) { rotate_to_fit = how; _image_data = QImage(); generateImage(); } } void ImageScrollView::setAutoScale(bool how) { scale_to_fit = how; if (!how) { rotate_to_fit = false; } _image_data = QImage(); + if (image_is_jpeg && how == false && image_scaled_loaded==true) { + loadJpeg(true); + } generateImage(); } ImageScrollView::~ImageScrollView() { } void ImageScrollView::rescaleImage(int w, int h) { if (_image_data.width()==w && _image_data.height()==h) { return; } double hs = (double)h / (double)_image_data.height() ; double ws = (double)w / (double)_image_data.width() ; double scaleFactor = (hs > ws) ? ws : hs; int smoothW = (int)(scaleFactor * _image_data.width()); int smoothH = (int)(scaleFactor * _image_data.height()); _image_data = _image_data.smoothScale(smoothW,smoothH); } void ImageScrollView::rotate_into_data(Rotation r) { /* realy - we must do this that way, 'cause when acting direct on _image_data the app will segfault :( */ QImage dest; int x, y; if ( _original_data.depth() > 8 ) { unsigned int *srcData, *destData; switch ( r ) { case Rotate90: dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned int *)_original_data.scanLine(y); for ( x=0; x < _original_data.width(); ++x ) { destData = (unsigned int *)dest.scanLine(x); destData[_original_data.height()-y-1] = srcData[x]; } } break; case Rotate180: dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned int *)_original_data.scanLine(y); destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1); for ( x=0; x < _original_data.width(); ++x ) destData[_original_data.width()-x-1] = srcData[x]; } break; case Rotate270: dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned int *)_original_data.scanLine(y); for ( x=0; x < _original_data.width(); ++x ) { destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1); destData[y] = srcData[x]; } } @@ -179,173 +245,181 @@ void ImageScrollView::rotate_into_data(Rotation r) unsigned int *srcTable, *destTable; switch ( r ) { case Rotate90: dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); dest.setNumColors(_original_data.numColors()); srcTable = (unsigned int *)_original_data.colorTable(); destTable = (unsigned int *)dest.colorTable(); for ( x=0; x < _original_data.numColors(); ++x ) destTable[x] = srcTable[x]; for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned char *)_original_data.scanLine(y); for ( x=0; x < _original_data.width(); ++x ) { destData = (unsigned char *)dest.scanLine(x); destData[_original_data.height()-y-1] = srcData[x]; } } break; case Rotate180: dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); dest.setNumColors(_original_data.numColors()); srcTable = (unsigned int *)_original_data.colorTable(); destTable = (unsigned int *)dest.colorTable(); for ( x=0; x < _original_data.numColors(); ++x ) destTable[x] = srcTable[x]; for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned char *)_original_data.scanLine(y); destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1); for ( x=0; x < _original_data.width(); ++x ) destData[_original_data.width()-x-1] = srcData[x]; } break; case Rotate270: dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); dest.setNumColors(_original_data.numColors()); srcTable = (unsigned int *)_original_data.colorTable(); destTable = (unsigned int *)dest.colorTable(); for ( x=0; x < _original_data.numColors(); ++x ) destTable[x] = srcTable[x]; for ( y=0; y < _original_data.height(); ++y ) { srcData = (unsigned char *)_original_data.scanLine(y); for ( x=0; x < _original_data.width(); ++x ) { destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1); destData[y] = srcData[x]; } } break; default: dest = _original_data; break; } } _image_data = dest; } void ImageScrollView::generateImage() { Rotation r = Rotate0; + { + QCopEnvelope( "QPE/System", "busy()" ); + } if (width()>height()&&_original_data.width()<_original_data.height() || width()<height()&&_original_data.width()>_original_data.height()) { if (rotate_to_fit) r = Rotate90; } + odebug << " r = " << r << oendl; if (scale_to_fit) { if (!_image_data.size().isValid()||width()>_image_data.width()||height()>_image_data.height()) { odebug << "Rescaling data" << oendl; if (r==Rotate0) { _image_data = _original_data; } else { rotate_into_data(r); } } rescaleImage(width(),height()); resizeContents(_image_data.width(),_image_data.height()); } else if (!first_resize_done||r!=last_rot||_image_data.width()==0) { if (r==Rotate0) { _image_data = _original_data; } else { rotate_into_data(r); } last_rot = r; resizeContents(_image_data.width(),_image_data.height()); } _pdata.convertFromImage(_image_data); - + /* * update the zoomer */ - check_zoomer(); + check_zoomer(); emit imageSizeChanged( _image_data.size() ); rescaleImage( 128, 128 ); /* * move scrollbar */ _zoomer->setGeometry( viewport()->width()-_image_data.width()/2, viewport()->height()-_image_data.height()/2, _image_data.width()/2, _image_data.height()/2 ); - + _zoomer->setImage( _image_data ); /* * invalidate */ _image_data=QImage(); + { + QCopEnvelope env( "QPE/System", "notBusy(QString)" ); + env << "Image generated"; + } } void ImageScrollView::resizeEvent(QResizeEvent * e) { odebug << "ImageScrollView resizeEvent" << oendl; QScrollView::resizeEvent(e); generateImage(); first_resize_done = true; emit viewportSizeChanged( viewport()->size() ); } void ImageScrollView::keyPressEvent(QKeyEvent * e) { if (!e) return; int dx = horizontalScrollBar()->lineStep(); int dy = verticalScrollBar()->lineStep(); if (e->key()==Qt::Key_Right) { scrollBy(dx,0); e->accept(); } else if (e->key()==Qt::Key_Left) { scrollBy(0-dx,0); e->accept(); } else if (e->key()==Qt::Key_Up) { scrollBy(0,0-dy); e->accept(); } else if (e->key()==Qt::Key_Down) { scrollBy(0,dy); e->accept(); } else { e->ignore(); } QScrollView::keyPressEvent(e); } void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph) { int w = clipw; int h = cliph; int x = clipx; int y = clipy; bool erase = false; if (!_pdata.size().isValid()) { p->fillRect(clipx,clipy,clipw,cliph,white); return; } if (w>_pdata.width()) { w=_pdata.width(); x = 0; erase = true; } else if (x+w>_pdata.width()){ x = _pdata.width()-w; } if (h>_pdata.height()) { h=_pdata.height(); y = 0; erase = true; } else if (y+h>_pdata.height()){ y = _pdata.height()-h; } if (erase||_original_data.hasAlphaBuffer()) { p->fillRect(clipx,clipy,clipw,cliph,white); } diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.h b/noncore/graphics/opie-eye/gui/imagescrollview.h index e209dfb..f6e187d 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.h +++ b/noncore/graphics/opie-eye/gui/imagescrollview.h @@ -1,75 +1,78 @@ #ifndef _IMAGE_SCROLL_VIEW_H #define _IMAGE_SCROLL_VIEW_H #include <lib/oimagezoomer.h> #include <qscrollview.h> #include <qimage.h> #include <qpixmap.h> #include <qstring.h> #include <qdialog.h> class QPainter; class ImageScrollView:public QScrollView { Q_OBJECT public: ImageScrollView( QWidget* parent, const char* name = 0, WFlags fl = 0 ); ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); virtual ~ImageScrollView(); virtual void setImage(const QImage&); virtual void setImage( const QString& path ); virtual void setDestructiveClose(); virtual void setAutoRotate(bool); virtual void setAutoScale(bool); virtual void setShowZoomer(bool); enum Rotation { Rotate0, Rotate90, Rotate180, Rotate270 }; signals: void sig_return(); void imageSizeChanged( const QSize& ); void viewportSizeChanged( const QSize& ); protected: virtual void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph ); void init(); Opie::MM::OImageZoomer *_zoomer; QImage _image_data; QImage _original_data; QPixmap _pdata; int _mouseStartPosX,_mouseStartPosY; bool scale_to_fit; bool rotate_to_fit; bool show_zoomer; bool first_resize_done; + bool image_is_jpeg; + bool image_scaled_loaded; Rotation last_rot; QString m_lastName; virtual void rescaleImage(int w, int h); virtual void rotate_into_data(Rotation r); virtual void generateImage(); + virtual void loadJpeg(bool interncall = false); bool image_fit_into(const QSize&s); void check_zoomer(); protected slots: virtual void viewportMouseMoveEvent(QMouseEvent* e); virtual void contentsMousePressEvent ( QMouseEvent * e); virtual void resizeEvent(QResizeEvent * e); virtual void keyPressEvent(QKeyEvent * e); }; #endif |