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[3]=='m') && ( 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::saveAsBase64( KoXmlWriter& writer ) const
00327 {
00328 if ( m_base )
00329 m_base->saveAsBase64( writer );
00330 return false;
00331 }
00332
00333 void KoPictureShared::clear(void)
00334 {
00335
00336 delete m_base;
00337 m_base=NULL;
00338 }
00339
00340 void KoPictureShared::clearAndSetMode(const QString& newMode)
00341 {
00342 delete m_base;
00343 m_base=NULL;
00344
00345 const QString mode=newMode.lower();
00346
00347 if ((mode=="svg") || (mode=="qpic"))
00348 {
00349 m_base=new KoPictureClipart();
00350 }
00351 else if (mode=="wmf")
00352 {
00353 m_base=new KoPictureWmf();
00354 }
00355 else if ( (mode=="eps") || (mode=="epsi") || (mode=="epsf") )
00356 {
00357 m_base=new KoPictureEps();
00358 }
00359 else
00360 {
00361 m_base=new KoPictureImage();
00362 }
00363 }
00364
00365 QString KoPictureShared::getExtension(void) const
00366 {
00367 return m_extension;
00368 }
00369
00370 void KoPictureShared::setExtension(const QString& extension)
00371 {
00372 m_extension = extension;
00373 }
00374
00375 QString KoPictureShared::getMimeType(void) const
00376 {
00377 if (m_base)
00378 return m_base->getMimeType(m_extension);
00379 return QString(NULL_MIME_TYPE);
00380 }
00381
00382
00383 bool KoPictureShared::loadFromBase64( const QCString& str )
00384 {
00385 clear();
00386 QByteArray data;
00387 KCodecs::base64Decode( str, data );
00388 return identifyAndLoad( data );
00389 }
00390
00391 bool KoPictureShared::load(QIODevice* io, const QString& extension)
00392 {
00393 kdDebug(30003) << "KoPictureShared::load(QIODevice*, const QString&) " << extension << endl;
00394 bool flag=false;
00395 QString ext(extension.lower());
00396 if (ext=="wmf")
00397 flag=loadWmf(io);
00398 else if (ext=="tmp")
00399 flag=loadTmp(io);
00400 else if ( ext == "bz2" )
00401 {
00402 flag = loadCompressed( io, "application/x-bzip2", "tmp" );
00403 }
00404 else if ( ext == "gz" )
00405 {
00406 flag = loadCompressed( io, "application/x-gzip", "tmp" );
00407 }
00408 else if ( ext == "svgz" )
00409 {
00410 flag = loadCompressed( io, "application/x-gzip", "svg" );
00411 }
00412 else
00413 {
00414 clearAndSetMode(ext);
00415 if (m_base)
00416 flag = m_base->load(io, ext);
00417 setExtension(ext);
00418 }
00419 if (!flag)
00420 {
00421 kdError(30003) << "File was not loaded! (KoPictureShared::load)" << endl;
00422 }
00423 return flag;
00424 }
00425
00426 bool KoPictureShared::loadFromFile(const QString& fileName)
00427 {
00428 kdDebug(30003) << "KoPictureShared::loadFromFile " << fileName << endl;
00429 if ( fileName.isEmpty() )
00430 {
00431 kdError(30003) << "Cannot load file with empty name!" << endl;
00432 return false;
00433 }
00434 QFile file(fileName);
00435 if (!file.open(IO_ReadOnly))
00436 return false;
00437
00438 bool flag = false;
00439 const int pos=fileName.findRev('.');
00440 if (pos==-1)
00441 {
00442 kdDebug(30003) << "File with no extension!" << endl;
00443
00444 flag = loadTmp( &file );
00445 }
00446 else
00447 {
00448 const QString extension( fileName.mid( pos+1 ) );
00449
00450 flag = load( &file, extension );
00451 }
00452 file.close();
00453 return flag;
00454 }
00455
00456 QSize KoPictureShared::getOriginalSize(void) const
00457 {
00458 if (m_base)
00459 return m_base->getOriginalSize();
00460 return QSize(0,0);
00461 }
00462
00463 QPixmap KoPictureShared::generatePixmap(const QSize& size, bool smoothScale)
00464 {
00465 if (m_base)
00466 return m_base->generatePixmap(size, smoothScale);
00467 return QPixmap();
00468 }
00469
00470 QDragObject* KoPictureShared::dragObject( QWidget *dragSource, const char *name )
00471 {
00472 if (m_base)
00473 return m_base->dragObject( dragSource, name );
00474 return 0L;
00475 }
00476
00477 QImage KoPictureShared::generateImage(const QSize& size)
00478 {
00479 if (m_base)
00480 return m_base->generateImage( size );
00481 return QImage();
00482 }
00483
00484 bool KoPictureShared::hasAlphaBuffer() const
00485 {
00486 if (m_base)
00487 return m_base->hasAlphaBuffer();
00488 return false;
00489 }
00490
00491 void KoPictureShared::setAlphaBuffer(bool enable)
00492 {
00493 if (m_base)
00494 m_base->setAlphaBuffer(enable);
00495 }
00496
00497 QImage KoPictureShared::createAlphaMask(int conversion_flags) const
00498 {
00499 if (m_base)
00500 return m_base->createAlphaMask(conversion_flags);
00501 return QImage();
00502 }
00503
00504 void KoPictureShared::clearCache(void)
00505 {
00506 if (m_base)
00507 m_base->clearCache();
00508 }
00509
00510 bool KoPictureShared::loadCompressed( QIODevice* io, const QString& mimeType, const QString& extension )
00511 {
00512
00513 QIODevice* in = KFilterDev::device( io, mimeType, false);
00514
00515 if ( !in )
00516 {
00517 kdError(30003) << "Cannot create device for uncompressing! Aborting!" << endl;
00518 return false;
00519 }
00520
00521
00522 if ( !in->open( IO_ReadOnly ) )
00523 {
00524 kdError(30003) << "Cannot open file for uncompressing! Aborting!" << endl;
00525 delete in;
00526 return false;
00527 }
00528
00529 const bool flag = load( in, extension );
00530
00531 in->close();
00532 delete in;
00533
00534 return flag;
00535 }