#include "imageringlist.h" #include #include #include #include using namespace std; const int DEFAULT_WIDTH = 3; class LoadRunable : public QRunnable { QString m_file; QObject *m_receiver; public: LoadRunable(const QString &file, QObject *receiver) : m_file(file), m_receiver(receiver) { } void run() { if(m_file.endsWith(".CR2", Qt::CaseInsensitive)) { LibRaw raw; raw.open_file(m_file.toLocal8Bit().data()); raw.imgdata.params.half_size = true; raw.imgdata.params.use_camera_wb = true; raw.imgdata.params.user_flip = 0; raw.unpack(); raw.dcraw_process(); libraw_processed_image_t *rawImg = raw.dcraw_make_mem_image(); QImage img(rawImg->width, rawImg->height, QImage::Format_RGB888); qDebug() << rawImg->width << img.width()*3 << img.scanLine(1)-img.scanLine(0); uint scanLine = rawImg->width*rawImg->colors; for(uint i=0; iheight; i++) { memcpy(img.scanLine(i), rawImg->data+(i*scanLine), scanLine); } raw.dcraw_clear_mem(rawImg); QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img)); } else { QImage img(m_file); QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img)); } } }; Image::Image(const QString name) : m_loading(false), m_released(true), m_name(name) { } void Image::load() { if(m_pixmap.isNull() && !m_loading) { m_loading = true; m_released = false; QThreadPool::globalInstance()->start(new LoadRunable(m_name, this)); } if(!m_loading && !m_pixmap.isNull()) emit pixmapLoaded(this); } void Image::release() { m_pixmap = QPixmap(); m_released = true; } QString Image::name() const { return m_name; } QPixmap Image::pixmap() const { return m_pixmap; } void Image::imageLoaded(QImage img) { m_loading = false; if(!m_released) { m_pixmap = QPixmap::fromImage(img); emit pixmapLoaded(this); } } ImageRingList::ImageRingList(QObject *parent) : QObject(parent) { connect(&m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString))); } bool ImageRingList::setDir(const QString path, const QString ¤tFile) { QDir dir(path); if(dir.exists()) { QStringList nameFilter; nameFilter << "*.jpg" << "*.png" << "*.cr2"; QStringList list = dir.entryList(nameFilter, QDir::Files | QDir::Readable, QDir::Name); QStringList absolutePaths; foreach(const QString &file, list) { absolutePaths.append(dir.absoluteFilePath(file)); } setFiles(absolutePaths, currentFile); m_fileSystemWatcher.removePaths(m_fileSystemWatcher.directories()); m_fileSystemWatcher.addPath(path); return true; } return false; } void ImageRingList::setFile(const QString &file) { QFileInfo info(file); setDir(info.absolutePath(), file); } ImagePtr ImageRingList::currentImage() { if(m_images.size()) return *m_currImage; else return 0; } void ImageRingList::increment() { if(m_images.size()) { (*m_firstImage)->release(); m_firstImage = increment(m_firstImage); m_currImage = increment(m_currImage); (*m_currImage)->load(); m_lastImage = increment(m_lastImage); (*m_lastImage)->load(); } } void ImageRingList::decrement() { if(m_images.size()) { (*m_lastImage)->release(); m_firstImage = decrement(m_firstImage); m_currImage = decrement(m_currImage); (*m_currImage)->load(); m_lastImage = decrement(m_lastImage); (*m_firstImage)->load(); } } void ImageRingList::setFiles(const QStringList files, const QString ¤tFile) { m_images.clear(); foreach(const QString &file, files) { ImagePtr ptr = make_shared(file); connect(ptr.get(), SIGNAL(pixmapLoaded(Image*)), this, SLOT(imageLoaded(Image*))); m_images.append(ptr); } int index = files.indexOf(currentFile); if(index < 0) index = 0; m_firstImage = m_currImage = m_lastImage = m_images.begin()+index; (*m_currImage)->load(); m_width = DEFAULT_WIDTHload(); m_lastImage = increment(m_lastImage); (*m_lastImage)->load(); } } QList::iterator ImageRingList::increment(QList::iterator iter) { iter++; if(iter == m_images.end()) iter = m_images.begin(); return iter; } QList::iterator ImageRingList::decrement(QList::iterator iter) { if(iter == m_images.begin()) iter = m_images.end(); iter--; return iter; } void ImageRingList::imageLoaded(Image *image) { if(image->name() == (*m_currImage)->name()) { emit pixmapLoaded(image->pixmap()); } } void ImageRingList::dirChanged(QString dir) { QString currentFile; if(m_images.size()) currentFile = (*m_currImage)->name(); setDir(dir, currentFile); emit currentImageChanged(); }