|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* This file is a part of digiKam project
|
|
|
|
* http://www.digikam.org
|
|
|
|
*
|
|
|
|
* Date : 2003-01-15
|
|
|
|
* Description : digiKam TDEIO slave to get image thumbnails.
|
|
|
|
* This tdeio-slave support this freedesktop
|
|
|
|
* specification about thumbnails mamagement:
|
|
|
|
* http://jens.triq.net/thumbnail-spec
|
|
|
|
*
|
|
|
|
* Copyright (C) 2003-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* Copyright (C) 2003-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it
|
|
|
|
* and/or modify it under the terms of the GNU General
|
|
|
|
* Public License as published by the Free Software Foundation;
|
|
|
|
* either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* ============================================================ */
|
|
|
|
|
|
|
|
#define XMD_H
|
|
|
|
#define PNG_BYTES_TO_CHECK 4
|
|
|
|
|
|
|
|
// C++ includes.
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
// TQt includes.
|
|
|
|
|
|
|
|
#include <tqcstring.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqdatastream.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqwmatrix.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
|
|
|
|
// KDE includes.
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <kinstance.h>
|
|
|
|
#include <kimageio.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kmdcodec.h>
|
|
|
|
#include <tdetempfile.h>
|
|
|
|
#include <ktrader.h>
|
|
|
|
#include <klibloader.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
#include <kprocess.h>
|
|
|
|
#include <tdeio/global.h>
|
|
|
|
#include <tdeio/thumbcreator.h>
|
|
|
|
#include <tdefilemetainfo.h>
|
|
|
|
|
|
|
|
// LibKDcraw includes.
|
|
|
|
|
|
|
|
#include <libkdcraw/version.h>
|
|
|
|
#include <libkdcraw/kdcraw.h>
|
|
|
|
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
|
|
#include <libkdcraw/dcrawbinary.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Local includes.
|
|
|
|
|
|
|
|
#include "dimg.h"
|
|
|
|
#include "dmetadata.h"
|
|
|
|
#include "jpegutils.h"
|
|
|
|
#include "digikamthumbnail.h"
|
|
|
|
#include "digikam_export.h"
|
|
|
|
|
|
|
|
// C Ansi includes.
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
#include <sys/shm.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <png.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
using namespace TDEIO;
|
|
|
|
using namespace Digikam;
|
|
|
|
|
|
|
|
tdeio_digikamthumbnailProtocol::tdeio_digikamthumbnailProtocol(int argc, char** argv)
|
|
|
|
: SlaveBase("tdeio_digikamthumbnail", argv[2], argv[3])
|
|
|
|
{
|
|
|
|
argc_ = argc;
|
|
|
|
argv_ = argv;
|
|
|
|
app_ = 0;
|
|
|
|
digiKamFingerPrint = TQString("Digikam Thumbnail Generator");
|
|
|
|
createThumbnailDirs();
|
|
|
|
}
|
|
|
|
|
|
|
|
tdeio_digikamthumbnailProtocol::~tdeio_digikamthumbnailProtocol()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void tdeio_digikamthumbnailProtocol::get(const KURL& url)
|
|
|
|
{
|
|
|
|
int size = metaData("size").toInt();
|
|
|
|
bool exif = (metaData("exif") == "yes");
|
|
|
|
|
|
|
|
cachedSize_ = (size <= 128) ? 128 : 256;
|
|
|
|
|
|
|
|
if (cachedSize_ <= 0)
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, i18n("No or invalid size specified"));
|
|
|
|
kdWarning() << "No or invalid size specified" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// generate the thumbnail path
|
|
|
|
TQString uri = KURL(url.path()).url(); // "file://" uri
|
|
|
|
KMD5 md5( TQFile::encodeName(uri).data() );
|
|
|
|
TQString thumbPath = (cachedSize_ == 128) ? smallThumbPath_ : bigThumbPath_;
|
|
|
|
thumbPath += TQFile::encodeName( md5.hexDigest() + ".png" ).data();
|
|
|
|
|
|
|
|
TQImage img;
|
|
|
|
bool regenerate = true;
|
|
|
|
|
|
|
|
// stat the original file
|
|
|
|
struct stat st;
|
|
|
|
if (::stat(TQFile::encodeName(url.path(-1)), &st) != 0)
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, i18n("File does not exist"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: if thumbnail have not been generated by digiKam (konqueror for example),
|
|
|
|
// force to recompute it, else we use it.
|
|
|
|
|
|
|
|
img = loadPNG(thumbPath);
|
|
|
|
if (!img.isNull())
|
|
|
|
{
|
|
|
|
if (img.text("Thumb::MTime") == TQString::number(st.st_mtime) &&
|
|
|
|
img.text("Software") == digiKamFingerPrint)
|
|
|
|
regenerate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (regenerate)
|
|
|
|
{
|
|
|
|
// To speed-up thumb extraction, we trying to load image using the file extension.
|
|
|
|
if ( !loadByExtension(img, url.path()) )
|
|
|
|
{
|
|
|
|
// Try JPEG loading : JPEG files without using Exif Thumb.
|
|
|
|
if ( !loadJPEG(img, url.path()) )
|
|
|
|
{
|
|
|
|
// Try to load with dcraw : RAW files.
|
|
|
|
if (!KDcrawIface::KDcraw::loadDcrawPreview(img, url.path()) )
|
|
|
|
{
|
|
|
|
// Try to load with DImg : TIFF, PNG, etc.
|
|
|
|
if (!loadDImg(img, url.path()) )
|
|
|
|
{
|
|
|
|
// Try to load with KDE thumbcreators : video files and others stuff.
|
|
|
|
loadKDEThumbCreator(img, url.path());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (img.isNull())
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, i18n("Cannot create thumbnail for %1")
|
|
|
|
.arg(url.prettyURL()));
|
|
|
|
kdWarning() << "Cannot create thumbnail for " << url.path() << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TQMAX(img.width(),img.height()) != cachedSize_)
|
|
|
|
img = img.smoothScale(cachedSize_, cachedSize_, TQ_ScaleMin);
|
|
|
|
|
|
|
|
if (img.depth() != 32)
|
|
|
|
img = img.convertDepth(32);
|
|
|
|
|
|
|
|
if (exif)
|
|
|
|
exifRotate(url.path(), img);
|
|
|
|
|
|
|
|
img.setText(TQString("Thumb::URI").latin1(), 0, uri);
|
|
|
|
img.setText(TQString("Thumb::MTime").latin1(), 0, TQString::number(st.st_mtime));
|
|
|
|
img.setText(TQString("Software").latin1(), 0, digiKamFingerPrint);
|
|
|
|
|
|
|
|
KTempFile temp(thumbPath + "-digikam-", ".png");
|
|
|
|
if (temp.status() == 0)
|
|
|
|
{
|
|
|
|
img.save(temp.name(), "PNG", 0);
|
|
|
|
::rename(TQFile::encodeName(temp.name()),
|
|
|
|
TQFile::encodeName(thumbPath));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
img = img.smoothScale(size, size, TQ_ScaleMin);
|
|
|
|
|
|
|
|
if (img.isNull())
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, "Thumbnail is null");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQByteArray imgData;
|
|
|
|
TQDataStream stream( imgData, IO_WriteOnly );
|
|
|
|
|
|
|
|
const TQString shmid = metaData("shmid");
|
|
|
|
if (shmid.isEmpty())
|
|
|
|
{
|
|
|
|
stream << img;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
void *shmaddr = shmat(shmid.toInt(), 0, 0);
|
|
|
|
|
|
|
|
if (shmaddr == (void *)-1)
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, "Failed to attach to shared memory segment " + shmid);
|
|
|
|
kdWarning() << "Failed to attach to shared memory segment " << shmid << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (img.width() * img.height() > cachedSize_ * cachedSize_)
|
|
|
|
{
|
|
|
|
error(TDEIO::ERR_INTERNAL, "Image is too big for the shared memory segment");
|
|
|
|
kdWarning() << "Image is too big for the shared memory segment" << endl;
|
|
|
|
shmdt((char*)shmaddr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream << img.width() << img.height() << img.depth();
|
|
|
|
memcpy(shmaddr, img.bits(), img.numBytes());
|
|
|
|
shmdt((char*)shmaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
data(imgData);
|
|
|
|
finished();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tdeio_digikamthumbnailProtocol::loadByExtension(TQImage& image, const TQString& path)
|
|
|
|
{
|
|
|
|
TQFileInfo fileInfo(path);
|
|
|
|
if (!fileInfo.exists())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Try to use embedded preview image from metadata.
|
|
|
|
DMetadata metadata(path);
|
|
|
|
if (metadata.getImagePreview(image))
|
|
|
|
{
|
|
|
|
kdDebug() << "Use Exif/Iptc preview extraction. Size of image: "
|
|
|
|
<< image.width() << "x" << image.height() << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else, use the right way depending of image file extension.
|
|
|
|
TQString ext = fileInfo.extension(false).upper();
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
|
|
TQString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles());
|
|
|
|
#else
|
|
|
|
TQString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!ext.isEmpty())
|
|
|
|
{
|
|
|
|
if (ext == TQString("JPEG") || ext == TQString("JPG") || ext == TQString("JPE"))
|
|
|
|
return (loadJPEG(image, path));
|
|
|
|
else if (ext == TQString("PNG"))
|
|
|
|
return (loadDImg(image, path));
|
|
|
|
else if (ext == TQString("TIFF") || ext == TQString("TIF"))
|
|
|
|
return (loadDImg(image, path));
|
|
|
|
else if (rawFilesExt.upper().contains(ext))
|
|
|
|
return (KDcrawIface::KDcraw::loadDcrawPreview(image, path));
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tdeio_digikamthumbnailProtocol::loadJPEG(TQImage& image, const TQString& path)
|
|
|
|
{
|
|
|
|
return Digikam::loadJPEGScaled(image, path, cachedSize_);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tdeio_digikamthumbnailProtocol::exifRotate(const TQString& filePath, TQImage& thumb)
|
|
|
|
{
|
|
|
|
// Rotate thumbnail based on metadata orientation information
|
|
|
|
|
|
|
|
DMetadata metadata(filePath);
|
|
|
|
DMetadata::ImageOrientation orientation = metadata.getImageOrientation();
|
|
|
|
|
|
|
|
if (orientation == DMetadata::ORIENTATION_NORMAL ||
|
|
|
|
orientation == DMetadata::ORIENTATION_UNSPECIFIED)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQWMatrix matrix;
|
|
|
|
|
|
|
|
switch (orientation)
|
|
|
|
{
|
|
|
|
case DMetadata::ORIENTATION_NORMAL:
|
|
|
|
case DMetadata::ORIENTATION_UNSPECIFIED:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_HFLIP:
|
|
|
|
matrix.scale(-1, 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_ROT_180:
|
|
|
|
matrix.rotate(180);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_VFLIP:
|
|
|
|
matrix.scale(1, -1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_ROT_90_HFLIP:
|
|
|
|
matrix.scale(-1, 1);
|
|
|
|
matrix.rotate(90);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_ROT_90:
|
|
|
|
matrix.rotate(90);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_ROT_90_VFLIP:
|
|
|
|
matrix.scale(1, -1);
|
|
|
|
matrix.rotate(90);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMetadata::ORIENTATION_ROT_270:
|
|
|
|
matrix.rotate(270);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// transform accordingly
|
|
|
|
thumb = thumb.xForm(matrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQImage tdeio_digikamthumbnailProtocol::loadPNG(const TQString& path)
|
|
|
|
{
|
|
|
|
png_uint_32 w32, h32;
|
|
|
|
int w, h;
|
|
|
|
bool has_alpha;
|
|
|
|
bool has_grey;
|
|
|
|
FILE *f;
|
|
|
|
png_structp png_ptr = NULL;
|
|
|
|
png_infop info_ptr = NULL;
|
|
|
|
int bit_depth, color_type, interlace_type;
|
|
|
|
|
|
|
|
has_alpha = 0;
|
|
|
|
has_grey = 0;
|
|
|
|
|
|
|
|
TQImage qimage;
|
|
|
|
|
|
|
|
f = fopen(path.latin1(), "rb");
|
|
|
|
if (!f)
|
|
|
|
return qimage;
|
|
|
|
|
|
|
|
unsigned char buf[PNG_BYTES_TO_CHECK];
|
|
|
|
|
|
|
|
fread(buf, 1, PNG_BYTES_TO_CHECK, f);
|
|
|
|
if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK))
|
|
|
|
{
|
|
|
|
fclose(f);
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
rewind(f);
|
|
|
|
|
|
|
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
|
|
|
{
|
|
|
|
fclose(f);
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
|
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
|
|
if (!info_ptr)
|
|
|
|
{
|
|
|
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
|
|
|
fclose(f);
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
|
|
|
{
|
|
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
|
|
|
fclose(f);
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
|
|
|
|
png_init_io(png_ptr, f);
|
|
|
|
png_read_info(png_ptr, info_ptr);
|
|
|
|
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
|
|
|
|
(png_uint_32 *) (&h32), &bit_depth, &color_type,
|
|
|
|
&interlace_type, NULL, NULL);
|
|
|
|
|
|
|
|
w = w32;
|
|
|
|
h = h32;
|
|
|
|
|
|
|
|
qimage.create(w, h, 32);
|
|
|
|
|
|
|
|
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
|
|
|
png_set_expand(png_ptr);
|
|
|
|
|
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
|
|
has_alpha = 1;
|
|
|
|
|
|
|
|
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
|
|
{
|
|
|
|
has_alpha = 1;
|
|
|
|
has_grey = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (color_type == PNG_COLOR_TYPE_GRAY)
|
|
|
|
has_grey = 1;
|
|
|
|
|
|
|
|
unsigned char **lines;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (has_alpha)
|
|
|
|
png_set_expand(png_ptr);
|
|
|
|
|
|
|
|
if (TQImage::systemByteOrder() == TQImage::LittleEndian)
|
|
|
|
{
|
|
|
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
|
|
|
png_set_bgr(png_ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
png_set_swap_alpha(png_ptr);
|
|
|
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 16bit color -> 8bit color */
|
|
|
|
if ( bit_depth == 16 )
|
|
|
|
png_set_strip_16(png_ptr);
|
|
|
|
|
|
|
|
/* pack all pixels to byte boundaires */
|
|
|
|
|
|
|
|
png_set_packing(png_ptr);
|
|
|
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
|
|
|
png_set_expand(png_ptr);
|
|
|
|
|
|
|
|
lines = (unsigned char **)malloc(h * sizeof(unsigned char *));
|
|
|
|
if (!lines)
|
|
|
|
{
|
|
|
|
png_read_end(png_ptr, info_ptr);
|
|
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
|
|
|
fclose(f);
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (has_grey)
|
|
|
|
{
|
|
|
|
png_set_gray_to_rgb(png_ptr);
|
|
|
|
if (png_get_bit_depth(png_ptr, info_ptr) < 8)
|
|
|
|
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sizeOfUint = sizeof(unsigned int);
|
|
|
|
for (i = 0 ; i < h ; i++)
|
|
|
|
lines[i] = ((unsigned char *)(qimage.bits())) + (i * w * sizeOfUint);
|
|
|
|
|
|
|
|
png_read_image(png_ptr, lines);
|
|
|
|
free(lines);
|
|
|
|
|
|
|
|
png_textp text_ptr;
|
|
|
|
int num_text=0;
|
|
|
|
png_get_text(png_ptr,info_ptr,&text_ptr,&num_text);
|
|
|
|
while (num_text--)
|
|
|
|
{
|
|
|
|
qimage.setText(text_ptr->key,0,text_ptr->text);
|
|
|
|
text_ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
png_read_end(png_ptr, info_ptr);
|
|
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
return qimage;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- Load using DImg ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool tdeio_digikamthumbnailProtocol::loadDImg(TQImage& image, const TQString& path)
|
|
|
|
{
|
|
|
|
Digikam::DImg dimg_im;
|
|
|
|
|
|
|
|
// to disable raw loader - does not work from ioslave
|
|
|
|
dimg_im.setAttribute("noeventloop", true);
|
|
|
|
|
|
|
|
if (!dimg_im.load(path))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
image = dimg_im.copyTQImage();
|
|
|
|
org_width_ = image.width();
|
|
|
|
org_height_ = image.height();
|
|
|
|
|
|
|
|
if ( TQMAX(org_width_, org_height_) != cachedSize_ )
|
|
|
|
{
|
|
|
|
TQSize sz(dimg_im.width(), dimg_im.height());
|
|
|
|
sz.scale(cachedSize_, cachedSize_, TQSize::ScaleMin);
|
|
|
|
image.scale(sz.width(), sz.height());
|
|
|
|
}
|
|
|
|
|
|
|
|
new_width_ = image.width();
|
|
|
|
new_height_ = image.height();
|
|
|
|
|
|
|
|
image.setAlphaBuffer(true) ;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- Load using KDE API ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool tdeio_digikamthumbnailProtocol::loadKDEThumbCreator(TQImage& image, const TQString& path)
|
|
|
|
{
|
|
|
|
// this sucks royally. some of the thumbcreators need an instance of
|
|
|
|
// app running so that they can use pixmap. till they get their
|
|
|
|
// code fixed, we will have to create a qapp instance.
|
|
|
|
if (!app_)
|
|
|
|
app_ = new TQApplication(argc_, argv_);
|
|
|
|
|
|
|
|
TQString mimeType = KMimeType::findByURL(path)->name();
|
|
|
|
if (mimeType.isEmpty())
|
|
|
|
{
|
|
|
|
kdDebug() << "Mimetype not found" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString mimeTypeAlt = mimeType.replace(TQRegExp("/.*"), "/*");
|
|
|
|
|
|
|
|
TQString plugin;
|
|
|
|
|
|
|
|
TDETrader::OfferList plugins = TDETrader::self()->query("ThumbCreator");
|
|
|
|
for (TDETrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it)
|
|
|
|
{
|
|
|
|
TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
|
|
|
|
for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
|
|
|
|
{
|
|
|
|
if ((*mt) == mimeType || (*mt) == mimeTypeAlt)
|
|
|
|
{
|
|
|
|
plugin=(*it)->library();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!plugin.isEmpty())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plugin.isEmpty())
|
|
|
|
{
|
|
|
|
kdDebug() << "No relevant plugin found " << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KLibrary *library = KLibLoader::self()->library(TQFile::encodeName(plugin));
|
|
|
|
if (!library)
|
|
|
|
{
|
|
|
|
kdDebug() << "Plugin library not found " << plugin << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbCreator *creator = 0;
|
|
|
|
newCreator create = (newCreator)library->symbol("new_creator");
|
|
|
|
if (create)
|
|
|
|
creator = create();
|
|
|
|
|
|
|
|
if (!creator)
|
|
|
|
{
|
|
|
|
kdDebug() << "Cannot load ThumbCreator " << plugin << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!creator->create(path, cachedSize_, cachedSize_, image))
|
|
|
|
{
|
|
|
|
kdDebug() << "Cannot create thumbnail for " << path << endl;
|
|
|
|
delete creator;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete creator;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tdeio_digikamthumbnailProtocol::createThumbnailDirs()
|
|
|
|
{
|
|
|
|
TQString path = TQDir::homeDirPath() + "/.thumbnails/";
|
|
|
|
|
|
|
|
smallThumbPath_ = path + "normal/";
|
|
|
|
bigThumbPath_ = path + "large/";
|
|
|
|
|
|
|
|
TDEStandardDirs::makeDir(smallThumbPath_, 0700);
|
|
|
|
TDEStandardDirs::makeDir(bigThumbPath_, 0700);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- TDEIO slave registration ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
DIGIKAM_EXPORT int kdemain(int argc, char **argv)
|
|
|
|
{
|
|
|
|
TDELocale::setMainCatalogue("digikam");
|
|
|
|
TDEInstance instance( "tdeio_digikamthumbnail" );
|
|
|
|
( void ) TDEGlobal::locale();
|
|
|
|
|
|
|
|
if (argc != 4)
|
|
|
|
{
|
|
|
|
kdDebug() << "Usage: tdeio_digikamthumbnail protocol domain-socket1 domain-socket2"
|
|
|
|
<< endl;
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
KImageIO::registerFormats();
|
|
|
|
|
|
|
|
tdeio_digikamthumbnailProtocol slave(argc, argv);
|
|
|
|
slave.dispatchLoop();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|