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