00001 /* 00002 Copyright © 2009-2010 Thibaut Cuvelier 00003 00004 This file is part of QExtend. 00005 00006 QExtend is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 any later version. 00010 00011 QExtend is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with QExtend. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include "devil-qt-handler.hpp" 00021 // Qt 00022 #include <QtCore/QIODevice> 00023 #include <QtCore/QVariant> 00024 #include <QtCore/QDataStream> 00025 // DevIL 00026 #include <IL/ilu.h> // seule la correction gamma nous impose cet header 00027 00028 using namespace QExtend::DevIL; 00029 00030 /* 00031 ** Initialise DevIL et autorise l'écrasement des fichiers 00032 ** 00033 ** Crée le Lump qui contiendra l'image en mémoire 00034 */ 00035 DevILHandler::DevILHandler( ) 00036 { 00037 ilInit( ); 00038 iluInit( ); 00039 } 00040 00041 /* 00042 ** Précise le format 00043 */ 00044 void DevILHandler::setFormat( const QByteArray & format ) 00045 { 00046 this->format = format; 00047 00048 switch( format ) 00049 { 00050 case "cut": 00051 this->I_Format = IL_CUT; 00052 break; 00053 case "dcx": 00054 this->I_Format = IL_DCX; 00055 break; 00056 case "exr": 00057 this->I_Format = IL_EXR; 00058 break; 00059 case "hdr": 00060 this->I_Format = IL_HDR; 00061 case "ico": 00062 case "cur": 00063 this->I_Format = IL_ICO; 00064 break; 00065 case "icns": 00066 this->I_Format = IL_ICNS; 00067 break; 00068 case "gif": 00069 this->I_Format = IL_GIF; 00070 break; 00071 case "jp2": 00072 this->I_Format = IL_JP2; 00073 break; 00074 case "lif": 00075 this->I_Format = IL_LIF; 00076 break; 00077 case "pcd": 00078 this->I_Format = IL_PCD; 00079 break; 00080 case "pic": 00081 this->I_Format = IL_PIC; 00082 break; 00083 case "psd": 00084 this->I_Format = IL_PSD; 00085 break; 00086 case "pdd": 00087 case "psp": 00088 this->I_Format = IL_PSP; 00089 break; 00090 case "wal": 00091 this->I_Format = IL_WAL; 00092 break; 00093 case "vtf": 00094 this->I_Format = IL_VTF; 00095 break; 00096 case "bmp": 00097 case "dib": 00098 this->I_Format = IL_BMP; 00099 break; 00100 case "dds": 00101 this->I_Format = IL_DDS; 00102 break; 00103 case "jpg": 00104 case "jpe": 00105 case "jpeg": 00106 this->I_Format = IL_JPG; 00107 break; 00108 case "pal": 00109 this->I_Format = IL_JASC_PAL; 00110 break; 00111 case "pcx": 00112 this->I_Format = IL_PCX; 00113 break; 00114 case "png": 00115 this->I_Format = IL_PNG; 00116 break; 00117 case "pnm": 00118 case "pgm": 00119 case "pnm": 00120 case "ppm": 00121 this->I_Format = IL_PNM; 00122 break; 00123 case "raw": 00124 this->I_Format = IL_RAW; 00125 break; 00126 case "sgi": 00127 case "bw": 00128 case "rgb": 00129 case "rgba": 00130 this->I_Format = IL_SGI; 00131 break; 00132 case "tif": 00133 case "tiff": 00134 this->I_Format = IL_TIF; 00135 break; 00136 case "tga": 00137 case "vda": 00138 case "icb": 00139 case "vst": 00140 this->I_Format = IL_TGA; 00141 break; 00142 default: 00143 this->I_Format = IL_TYPE_UNKNOWN; 00144 break; 00145 } 00146 } 00147 00148 /* 00149 ** Récupère le format 00150 */ 00151 ILenum DevILHandler::format( ) const 00152 { 00153 return this->I_Format; 00154 } 00155 00156 QByteArray DevILHandler::format( ) const 00157 { 00158 return this->format; 00159 } 00160 00161 /* 00162 ** Récupère le QIODevice à partir duquel tout est effectué 00163 */ 00164 QIODevice * DevILHandler::device( ) const 00165 { 00166 return this->Device; 00167 } 00168 00169 /* 00170 ** Précise le périphérique à partir duquel la lecture sera effectuée 00171 ** Pas de retour autorisé => pas de retour, même en cas d'erreur ... 00172 */ 00173 void DevILHandler::setDevice( QIODevice *device ) 00174 { 00175 this->Device = device; 00176 this->Size = this->Device->size ( ); 00177 this->Lump = ( char * ) malloc ( this->Size ); 00178 this->Device->peek(this->Lump, this->Size); 00179 ilLoadL ( IL_TYPE_UNKNOWN, this->Lump, this->Size ); 00180 00181 this->Width = ilGetInteger ( IL_IMAGE_WIDTH ); 00182 this->Height = ilGetInteger ( IL_IMAGE_HEIGHT ); 00183 this->Depth = ilGetInteger ( IL_IMAGE_DEPTH ); 00184 this->Size_wh = QSize ( this->Width, this->Height ); 00185 this->Palette = ilGetInteger ( IL_PALETTE_BASE_TYPE ); 00186 this->NumImages = ilGetInteger ( IL_NUM_IMAGES ); 00187 this->DurImage = ilGetInteger ( IL_IMAGE_DURATION ); 00188 this->Gamma = 1.0; 00189 this->Data = ilGetData ( ); 00190 // Determine QImage::Format from DevIL palette 00191 if( this->Palette == IL_RGB ) 00192 { 00193 this->Q_Format = QImage::Format_RGB32; 00194 } 00195 else if( this->Palette == IL_RGBA ) 00196 { 00197 this->Q_Format = QImage::Format_ARGB32; 00198 } 00199 else if( this->Palette = IL_COLOUR_INDEX ) 00200 { 00201 this->Q_Format = QImage::Format_Indexed8; 00202 } 00203 else if( this->Palette = IL_COLOR_INDEX ) 00204 { 00205 this->Q_Format = QImage::Format_Indexed8; 00206 } 00207 else 00208 { 00209 this->Q_Format = QImage::Format_Invalid; // DevIL itself does not know... 00210 } 00211 } 00212 00213 /* 00214 ** Utilisent les fonctions prévues de DevIL pour la validité des fichiers ( extensions + format ) 00215 ** et de Qt ( lecture possible ? ) 00216 */ 00217 bool DevILHandler::canRead( ) const 00218 /* 00219 -- On ne sait rien du périphérique : qu'est-ce que l'on peut en dire ?! 00220 -- S'il est déjà chargé, alors on peut en dire quelque chose 00221 */ 00222 { 00223 if( this->device( ) == 0 ); 00224 { 00225 qWarning( "DevILHandler::canRead( ) called with no device" ); 00226 return false; 00227 } 00228 00229 return ilIsValidL( IL_TYPE_UNKNOWN, this->Lump, this->Size ); 00230 } 00231 /* 00232 -- On a le périphérique, mais aucun moyen d'accès direct ... C'est parti pour la triche ! 00233 */ 00234 bool DevILHandler::canRead( QIODevice *device ) 00235 { 00236 if ( ! device ) 00237 { 00238 qWarning( "DevILHandler::canRead( ) called with no device or an unusable device" ); 00239 return false; 00240 } 00241 00242 this->setDevice( device ); 00243 00244 /* 00245 -- DevIL connaît enfin le contenu et la taille du fichier chargé du QIODevice (ouf !) 00246 -- Surtout, le lump est du bon format ... 00247 -- 00248 -- Maintenant, on vérifie le format (que l'on ne connaît toujours pas...) 00249 */ 00250 00251 return ilIsValidL( IL_TYPE_UNKNOWN, this->Lump, this->Size ); 00252 } 00253 00254 /* 00255 ** Lit l'image 00256 ** Image forcément déjà chargée précédemment, par canRead (donc setDevice) 00257 */ 00258 bool DevILHandler::read ( QImage * image ) 00259 { 00260 this->Image = QImage ( this->Size_wh, this->Q_Format ); 00261 this->Image.fromData( this->Data, this->Size, 0 ); 00262 image = this->Image; 00263 return true; 00264 } 00265 00266 /* 00267 ** Écrit l'image 00268 */ 00269 bool DevILHandler::write ( const QImage & image ) 00270 { 00271 if( ! this->Device->isWritable( ) ) 00272 { 00273 return false; 00274 } 00275 //nous ne connaissons pas d'avance la taille du fichier résultant ==> 0 00276 if( ilSaveL( this->I_Format, this->Lump, 0 ) == 0 ) 00277 { 00278 return false; 00279 } 00280 if( this->Device->write( this->Lump ) == -1 ) 00281 { 00282 return false; 00283 } 00284 return true; 00285 } 00286 00287 /* 00288 ** Gestion des images animées ( GIF... ) 00289 */ 00290 int DevILHandler::imageCount( ) 00291 const 00292 { 00293 if( this->I_Format != IL_GIF ) 00294 { 00295 return 0; 00296 } 00297 else 00298 { 00299 return this->NumImages; 00300 } 00301 } 00302 00303 int DevILHandler::loopCount( ) 00304 const 00305 { 00306 if( this->I_Format != IL_GIF ) 00307 { 00308 return 0; 00309 } 00310 else 00311 { 00312 return 1; 00313 } 00314 } 00315 00316 int DevILHandler::nextImageDelay( ) 00317 const 00318 { 00319 if( this->I_Format != IL_GIF ) 00320 { 00321 return 0; 00322 } 00323 else 00324 { 00325 return this->DurImage; 00326 } 00327 } 00328 00329 bool DevILHandler::jumpToImage( int imageNumber ) const 00330 { 00331 return false; 00332 } 00333 00334 /* 00335 ** Gestion des ImageOption 00336 */ 00337 QVariant DevILHandler::option( QImageIOHandler::ImageOption option ) 00338 const 00339 { 00340 if( option == QImageIOHandler::Size ) 00341 { 00342 return this->Size_wh; 00343 } 00344 else if( option == QImageIOHandler::Gamma ) 00345 { 00346 return this->Gamma; 00347 } 00348 else if( option == QImageIOHandler::Animation ) 00349 { 00350 if( this->I_Format == IL_GIF ) 00351 { 00352 return true; 00353 } 00354 else 00355 { 00356 return false; 00357 } 00358 } 00359 else 00360 { 00361 return false; 00362 } 00363 } 00364 00365 void DevILHandler::setOption( QImageIOHandler::ImageOption option, const QVariant & value ) 00366 { 00367 if ( option == QImageIOHandler::Gamma ) 00368 { 00369 this->Gamma = value.toDouble( ); 00370 iluGammaCorrect( this->Gamma ); 00371 } 00372 } 00373 00374 bool DevILHandler::supportsOption( QImageIOHandler::ImageOption option ) 00375 const 00376 { 00377 if( option == QImageIOHandler::Size ) 00378 { 00379 return true; 00380 } 00381 else if( option == QImageIOHandler::Gamma ) 00382 { 00383 return true; 00384 } 00385 else if( option == QImageIOHandler::Animation ) 00386 { 00387 return true; 00388 } 00389 else 00390 { 00391 return false; 00392 } 00393 }
Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.