4
#include <qdatastream.h>
9
#include <kio/global.h>
21
#include <sys/types.h>
27
#include "digikamthumbnail.h"
32
kio_digikamthumbnailProtocol::kio_digikamthumbnailProtocol(const QCString &pool_socket,
33
const QCString &app_socket)
34
: SlaveBase("kio_digikamthumbnail", pool_socket, app_socket)
39
kio_digikamthumbnailProtocol::~kio_digikamthumbnailProtocol()
44
void kio_digikamthumbnailProtocol::get(const KURL& url )
46
size_ = metaData("size").toInt();
48
error(KIO::ERR_INTERNAL, "No or invalid size specified");
49
kdWarning() << "No or invalid size specified" << endl;
55
if (!loadJPEG(img, url.path()))
59
error(KIO::ERR_INTERNAL, "Cannot create thumbnail for " + url.path());
60
kdWarning() << "Cannot create thumbnail for " << url.path() << endl;
64
if (QMAX(img.width(),img.height()) != size_)
65
img = img.smoothScale(size_,size_,QImage::ScaleMin);
67
if (img.depth() != 32)
68
img = img.convertDepth(32);
71
QDataStream stream( imgData, IO_WriteOnly );
73
QString shmid = metaData("shmid");
74
if (shmid.isEmpty()) {
79
void *shmaddr = shmat(shmid.toInt(), 0, 0);
80
if (shmaddr == (void *)-1)
82
error(KIO::ERR_INTERNAL,
83
"Failed to attach to shared memory segment "
85
kdWarning() << "Failed to attach to shared memory segment "
89
if (img.width() * img.height() > size_ * size_)
91
error(KIO::ERR_INTERNAL,
92
"Image is too big for the shared memory segment");
93
kdWarning() << "Image is too big for the shared memory segment"
95
shmdt((char*)shmaddr);
98
stream << img.width() << img.height() << img.depth();
99
memcpy(shmaddr, img.bits(), img.numBytes());
100
shmdt((char*)shmaddr);
107
struct myjpeg_error_mgr : public jpeg_error_mgr
109
jmp_buf setjmp_buffer;
114
static void myjpeg_error_exit(j_common_ptr cinfo)
116
myjpeg_error_mgr* myerr =
117
(myjpeg_error_mgr*) cinfo->err;
119
char buffer[JMSG_LENGTH_MAX];
120
(*cinfo->err->format_message)(cinfo, buffer);
121
kdWarning() << buffer << endl;
122
longjmp(myerr->setjmp_buffer, 1);
126
bool kio_digikamthumbnailProtocol::loadJPEG(QImage& image,
129
QString format=QImageIO::imageFormat(path);
130
if (format !="JPEG") return false;
132
FILE* inputFile=fopen(path.latin1(), "rb");
136
struct jpeg_decompress_struct cinfo;
137
struct myjpeg_error_mgr jerr;
139
// JPEG error handling - thanks to Marcus Meissner
140
cinfo.err = jpeg_std_error(&jerr);
141
cinfo.err->error_exit = myjpeg_error_exit;
143
if (setjmp(jerr.setjmp_buffer)) {
144
jpeg_destroy_decompress(&cinfo);
149
jpeg_create_decompress(&cinfo);
150
jpeg_stdio_src(&cinfo, inputFile);
151
jpeg_read_header(&cinfo, TRUE);
153
int imgSize = QMAX(cinfo.image_width, cinfo.image_height);
156
while(size_*scale*2<=imgSize) {
162
cinfo.scale_denom=scale;
165
jpeg_start_decompress(&cinfo);
169
switch(cinfo.output_components) {
172
img.create( cinfo.output_width, cinfo.output_height, 32 );
175
img.create( cinfo.output_width, cinfo.output_height,
177
for (int i=0; i<256; i++)
178
img.setColor(i, qRgb(i,i,i));
184
uchar** lines = img.jumpTable();
185
while (cinfo.output_scanline < cinfo.output_height)
186
jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline,
187
cinfo.output_height);
188
jpeg_finish_decompress(&cinfo);
191
if ( cinfo.output_components == 3 ) {
192
for (uint j=0; j<cinfo.output_height; j++) {
193
uchar *in = img.scanLine(j) + cinfo.output_width*3;
194
QRgb *out = (QRgb*)( img.scanLine(j) );
196
for (uint i=cinfo.output_width; i--; ) {
198
out[i] = qRgb(in[0], in[1], in[2]);
203
int newMax = QMAX(cinfo.output_width, cinfo.output_height);
204
int newx = size_*cinfo.output_width / newMax;
205
int newy = size_*cinfo.output_height / newMax;
207
jpeg_destroy_decompress(&cinfo);
210
image = img.smoothScale(newx,newy);
219
int kdemain(int argc, char **argv)
221
KInstance instance( "kio_digikamthumbnail" );
223
kdDebug() << "*** Starting kio_digikamthumbnail " << endl;
226
kdDebug() << "Usage: kio_digikamthumbnail protocol domain-socket1 domain-socket2" << endl;
230
KImageIO::registerFormats();
232
kio_digikamthumbnailProtocol slave(argv[2], argv[3]);
233
slave.dispatchLoop();
235
kdDebug() << "*** kio_digikamthumbnail Done" << endl;