00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <QFile>
00022 #include <QImageReader>
00023 #include <QImageWriter>
00024 #include <QPainter>
00025
00026 #include <QPixmap>
00027
00028 #include <kdebug.h>
00029 #include <kurl.h>
00030 #include <kfilterdev.h>
00031 #include <kio/netaccess.h>
00032 #include <QBuffer>
00033 #include "KoPictureKey.h"
00034 #include "KoPictureBase.h"
00035 #include "KoPictureImage.h"
00036 #include "KoPictureEps.h"
00037 #include "KoPictureClipart.h"
00038 #include "KoPictureWmf.h"
00039 #include "KoPictureShared.h"
00040 #include <kcodecs.h>
00041
00042
00043 KoPictureShared::KoPictureShared(void) : m_base(NULL)
00044 {
00045 }
00046
00047 void KoPictureShared::assignPictureId( uint _id)
00048 {
00049 m_pictureId = _id;
00050 }
00051
00052 QString KoPictureShared::uniquePictureId() const
00053 {
00054 return "Pictures"+ QString::number(m_pictureId);
00055 }
00056
00057 KoPictureShared::~KoPictureShared(void)
00058 {
00059 delete m_base;
00060 }
00061
00062 KoPictureShared::KoPictureShared(const KoPictureShared &other)
00063 : Q3Shared()
00064 {
00065
00066 if (other.m_base)
00067 m_base=other.m_base->newCopy();
00068 else
00069 m_base=NULL;
00070 }
00071
00072 KoPictureShared& KoPictureShared::operator=( const KoPictureShared &other )
00073 {
00074 clear();
00075 kDebug(30003) << "KoPictureShared::= before" << endl;
00076 if (other.m_base)
00077 m_base=other.m_base->newCopy();
00078 kDebug(30003) << "KoPictureShared::= after" << endl;
00079 return *this;
00080 }
00081
00082 KoPictureType::Type KoPictureShared::getType(void) const
00083 {
00084 if (m_base)
00085 return m_base->getType();
00086 return KoPictureType::TypeUnknown;
00087 }
00088
00089 bool KoPictureShared::isNull(void) const
00090 {
00091 if (m_base)
00092 return m_base->isNull();
00093 return true;
00094 }
00095
00096 void KoPictureShared::draw(QPainter& painter, int x, int y, int width, int height, int sx, int sy, int sw, int sh, bool fastMode)
00097 {
00098 if (m_base)
00099 m_base->draw(painter, x, y, width, height, sx, sy, sw, sh, fastMode);
00100 else
00101 {
00102
00103 kWarning(30003) << "Drawing red rectangle! (KoPictureShared::draw)" << endl;
00104 painter.save();
00105 painter.setBrush(QColor(255,0,0));
00106 painter.drawRect(x,y,width,height);
00107 painter.restore();
00108 }
00109 }
00110
00111 bool KoPictureShared::loadWmf(QIODevice* io)
00112 {
00113 kDebug(30003) << "KoPictureShared::loadWmf" << endl;
00114 if (!io)
00115 {
00116 kError(30003) << "No QIODevice!" << endl;
00117 return false;
00118 }
00119
00120 clear();
00121
00122
00123
00124
00125 QByteArray array ( io->readAll() );
00126
00127 if ((array[0]=='Q') && (array[1]=='P') &&(array[2]=='I') && (array[3]=='C'))
00128 {
00129 m_base=new KoPictureClipart();
00130 setExtension("qpic");
00131 }
00132 else
00133 {
00134 m_base=new KoPictureWmf();
00135 setExtension("wmf");
00136 }
00137 return m_base->loadData(array, m_extension);
00138 }
00139
00140 bool KoPictureShared::loadTmp(QIODevice* io)
00141
00142
00143 {
00144 kDebug(30003) << "KoPictureShared::loadTmp" << endl;
00145 if (!io)
00146 {
00147 kError(30003) << "No QIODevice!" << endl;
00148 return false;
00149 }
00150
00151
00152
00153
00154 QByteArray array ( io->readAll() );
00155 return identifyAndLoad( array );
00156 }
00157
00158 bool KoPictureShared::identifyAndLoad( QByteArray array )
00159 {
00160 if ( array.size() < 5 )
00161 {
00162 kError(30003) << "Picture is less than 5 bytes long!" << endl;
00163 return false;
00164 }
00165
00166 QString strExtension;
00167 bool flag=false;
00168
00169
00170
00171 if ((array[0]==char(0x89)) && (array[1]=='P') &&(array[2]=='N') && (array[3]=='G'))
00172 {
00173 strExtension="png";
00174 }
00175 else if ((array[0]==char(0xff)) && (array[1]==char(0xd8)) &&(array[2]==char(0xff)) && (array[3]==char(0xe0)))
00176 {
00177 strExtension="jpeg";
00178 }
00179 else if ((array[0]=='B') && (array[1]=='M'))
00180 {
00181 strExtension="bmp";
00182 }
00183 else if ((array[0]==char(0xd7)) && (array[1]==char(0xcd)) &&(array[2]==char(0xc6)) && (array[3]==char(0x9a)))
00184 {
00185 strExtension="wmf";
00186 }
00187 else if ((array[0]=='<') && (array[1]=='?') && ( array[2]=='x' ) && (array[3]=='m') && ( array[4]=='l' ) )
00188 {
00189 strExtension="svg";
00190 }
00191 else if ((array[0]=='Q') && (array[1]=='P') &&(array[2]=='I') && (array[3]=='C'))
00192 {
00193 strExtension="qpic";
00194 }
00195 else if ((array[0]=='%') && (array[1]=='!') &&(array[2]=='P') && (array[3]=='S'))
00196 {
00197 strExtension="eps";
00198 }
00199 else if ((array[0]==char(0xc5)) && (array[1]==char(0xd0)) && (array[2]==char(0xd3)) && (array[3]==char(0xc6)))
00200 {
00201
00202 strExtension="eps";
00203 }
00204 else if ((array[0]=='G') && (array[1]=='I') && (array[2]=='F') && (array[3]=='8'))
00205 {
00206
00207 strExtension="gif";
00208 }
00209 else if ( ( array[0] == char( 0037 ) ) && ( array[1] == char( 0213 ) ) )
00210 {
00211
00212 QBuffer buffer(&array);
00213 buffer.open(QIODevice::ReadOnly);
00214
00215 const bool flag = loadCompressed( &buffer, "application/x-gzip", "tmp" );
00216 buffer.close();
00217 return flag;
00218 }
00219 else if ( ( array[0] == 'B' ) && ( array[1] == 'Z' ) && ( array[2] == 'h') )
00220 {
00221
00222 QBuffer buffer(&array);
00223 buffer.open(QIODevice::ReadOnly);
00224 const bool flag = loadCompressed( &buffer, "application/x-bzip2", "tmp" );
00225 buffer.close();
00226 return flag;
00227 }
00228 else
00229 {
00230 kDebug(30003) << "Cannot identify the type of temp file!"
00231 << " Trying to convert to PNG! (in KoPictureShared::loadTmp" << endl;
00232
00233
00234
00235
00236 QBuffer buf( &array );
00237 if (!buf.open(QIODevice::ReadOnly))
00238 {
00239 kError(30003) << "Could not open read buffer!" << endl;
00240 return false;
00241 }
00242
00243 QImageReader imageReader( &buf );
00244 QImage image = imageReader.read();
00245 if ( image.isNull() )
00246 {
00247 kError(30003) << "Could not read image!" << endl;
00248 return false;
00249 }
00250 buf.close();
00251
00252 if ( !buf.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
00253 {
00254 kError(30003) << "Could not open write buffer!" << endl;
00255 return false;
00256 }
00257
00258 QImageWriter imageWriter( &buf, "PNG" );
00259
00260 if ( !imageWriter.write( image ) )
00261 {
00262 kError(30003) << "Could not write converted image!" << endl;
00263 return false;
00264 }
00265 buf.close();
00266
00267 array = buf.buffer();
00268
00269 strExtension="png";
00270 }
00271
00272 kDebug(30003) << "Temp file considered to be " << strExtension << endl;
00273
00274 clearAndSetMode(strExtension);
00275 if (m_base)
00276 flag = m_base->loadData(array,strExtension);
00277 setExtension(strExtension);
00278
00279 return flag;
00280 }
00281
00282
00283
00284 bool KoPictureShared::loadXpm(QIODevice* io)
00285 {
00286 kDebug(30003) << "KoPictureShared::loadXpm" << endl;
00287 if (!io)
00288 {
00289 kError(30003) << "No QIODevice!" << endl;
00290 return false;
00291 }
00292
00293 clear();
00294
00295
00296
00297
00298 QByteArray array = io->readAll();
00299
00300
00301
00302 int pos=0;
00303
00304 while ( (pos = array.indexOf( char(1), pos ) )!=-1)
00305 {
00306 array[pos]='"';
00307 }
00308
00309
00310
00311 m_base=new KoPictureImage();
00312
00313 QBuffer buffer(&array);
00314 bool check = m_base->load(&buffer,"xpm");
00315 setExtension("xpm");
00316 return check;
00317 }
00318
00319 bool KoPictureShared::save(QIODevice* io) const
00320 {
00321 if (!io)
00322 return false;
00323 if (m_base)
00324 return m_base->save(io);
00325 return false;
00326 }
00327
00328 bool KoPictureShared::saveAsBase64( KoXmlWriter& writer ) const
00329 {
00330 if ( m_base )
00331 m_base->saveAsBase64( writer );
00332 return false;
00333 }
00334
00335 void KoPictureShared::clear(void)
00336 {
00337
00338 delete m_base;
00339 m_base=NULL;
00340 }
00341
00342 void KoPictureShared::clearAndSetMode(const QString& newMode)
00343 {
00344 delete m_base;
00345 m_base=NULL;
00346
00347 const QString mode = newMode.toLower();
00348
00349 if ((mode=="svg") || (mode=="qpic"))
00350 {
00351 m_base=new KoPictureClipart();
00352 }
00353 else if (mode=="wmf")
00354 {
00355 m_base=new KoPictureWmf();
00356 }
00357 else if ( (mode=="eps") || (mode=="epsi") || (mode=="epsf") )
00358 {
00359 m_base=new KoPictureEps();
00360 }
00361 else
00362 {
00363 m_base=new KoPictureImage();
00364 }
00365 }
00366
00367 QString KoPictureShared::getExtension(void) const
00368 {
00369 return m_extension;
00370 }
00371
00372 void KoPictureShared::setExtension(const QString& extension)
00373 {
00374 m_extension = extension;
00375 }
00376
00377 QString KoPictureShared::getMimeType(void) const
00378 {
00379 if (m_base)
00380 return m_base->getMimeType(m_extension);
00381 return QString(NULL_MIME_TYPE);
00382 }
00383
00384
00385 bool KoPictureShared::loadFromBase64( const QByteArray& str )
00386 {
00387 clear();
00388 QByteArray data;
00389 KCodecs::base64Decode( str, data );
00390 return identifyAndLoad( data );
00391 }
00392
00393 bool KoPictureShared::load(QIODevice* io, const QString& extension)
00394 {
00395 kDebug(30003) << "KoPictureShared::load(QIODevice*, const QString&) " << extension << endl;
00396 bool flag=false;
00397 QString ext( extension.toLower() );
00398 if (ext=="wmf")
00399 flag=loadWmf(io);
00400 else if (ext=="tmp")
00401 flag=loadTmp(io);
00402 else if ( ext == "bz2" )
00403 {
00404 flag = loadCompressed( io, "application/x-bzip2", "tmp" );
00405 }
00406 else if ( ext == "gz" )
00407 {
00408 flag = loadCompressed( io, "application/x-gzip", "tmp" );
00409 }
00410 else if ( ext == "svgz" )
00411 {
00412 flag = loadCompressed( io, "application/x-gzip", "svg" );
00413 }
00414 else
00415 {
00416 clearAndSetMode(ext);
00417 if (m_base)
00418 flag = m_base->load(io, ext);
00419 setExtension(ext);
00420 }
00421 if (!flag)
00422 {
00423 kError(30003) << "File was not loaded! (KoPictureShared::load)" << endl;
00424 }
00425 return flag;
00426 }
00427
00428 bool KoPictureShared::loadFromFile(const QString& fileName)
00429 {
00430 kDebug(30003) << "KoPictureShared::loadFromFile " << fileName << endl;
00431 if ( fileName.isEmpty() )
00432 {
00433 kError(30003) << "Cannot load file with empty name!" << endl;
00434 return false;
00435 }
00436 QFile file(fileName);
00437 if (!file.open(QIODevice::ReadOnly))
00438 return false;
00439
00440 bool flag = false;
00441 const int pos = fileName.lastIndexOf('.');
00442 if (pos==-1)
00443 {
00444 kDebug(30003) << "File with no extension!" << endl;
00445
00446 flag = loadTmp( &file );
00447 }
00448 else
00449 {
00450 const QString extension( fileName.mid( pos+1 ) );
00451
00452 flag = load( &file, extension );
00453 }
00454 file.close();
00455 return flag;
00456 }
00457
00458 QSize KoPictureShared::getOriginalSize(void) const
00459 {
00460 if (m_base)
00461 return m_base->getOriginalSize();
00462 return QSize(0,0);
00463 }
00464
00465 QPixmap KoPictureShared::generatePixmap(const QSize& size, bool smoothScale)
00466 {
00467 if (m_base)
00468 return m_base->generatePixmap(size, smoothScale);
00469 return QPixmap();
00470 }
00471
00472 Q3DragObject* KoPictureShared::dragObject( QWidget *dragSource, const char *name )
00473 {
00474 if (m_base)
00475 return m_base->dragObject( dragSource, name );
00476 return 0L;
00477 }
00478
00479 QImage KoPictureShared::generateImage(const QSize& size)
00480 {
00481 if (m_base)
00482 return m_base->generateImage( size );
00483 return QImage();
00484 }
00485
00486 bool KoPictureShared::hasAlphaBuffer() const
00487 {
00488 if (m_base)
00489 return m_base->hasAlphaBuffer();
00490 return false;
00491 }
00492
00493 void KoPictureShared::setAlphaBuffer(bool enable)
00494 {
00495 if (m_base)
00496 m_base->setAlphaBuffer(enable);
00497 }
00498
00499 QImage KoPictureShared::createAlphaMask(Qt::ImageConversionFlags flags) const
00500 {
00501 if (m_base)
00502 return m_base->createAlphaMask(flags);
00503 return QImage();
00504 }
00505
00506 void KoPictureShared::clearCache(void)
00507 {
00508 if (m_base)
00509 m_base->clearCache();
00510 }
00511
00512 bool KoPictureShared::loadCompressed( QIODevice* io, const QString& mimeType, const QString& extension )
00513 {
00514
00515 QIODevice* in = KFilterDev::device( io, mimeType, false);
00516
00517 if ( !in )
00518 {
00519 kError(30003) << "Cannot create device for uncompressing! Aborting!" << endl;
00520 return false;
00521 }
00522
00523
00524 if ( !in->open( QIODevice::ReadOnly ) )
00525 {
00526 kError(30003) << "Cannot open file for uncompressing! Aborting!" << endl;
00527 delete in;
00528 return false;
00529 }
00530
00531 const bool flag = load( in, extension );
00532
00533 in->close();
00534 delete in;
00535
00536 return flag;
00537 }