692613e5 |
1 | // Created on: 2010-09-16 |
2 | // Created by: KGV |
973c2be1 |
3 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
692613e5 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
692613e5 |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
692613e5 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
692613e5 |
15 | |
a975e06e |
16 | #if !defined(HAVE_FREEIMAGE) && defined(_WIN32) |
17 | #define HAVE_WINCODEC |
18 | #endif |
19 | |
692613e5 |
20 | #ifdef HAVE_FREEIMAGE |
21 | #include <FreeImage.h> |
22 | |
23 | #ifdef _MSC_VER |
24 | #pragma comment( lib, "FreeImage.lib" ) |
25 | #endif |
a975e06e |
26 | #elif defined(HAVE_WINCODEC) |
27 | //#include <initguid.h> |
28 | #include <wincodec.h> |
29 | #undef min |
30 | #undef max |
692613e5 |
31 | #endif |
32 | |
33 | #include <Image_AlienPixMap.hxx> |
34 | #include <gp.hxx> |
0c015ee2 |
35 | #include <Message.hxx> |
36 | #include <Message_Messenger.hxx> |
88b12b7c |
37 | #include <NCollection_Array1.hxx> |
38 | #include <Standard_ArrayStreamBuffer.hxx> |
692613e5 |
39 | #include <TCollection_AsciiString.hxx> |
7aa1b65c |
40 | #include <TCollection_ExtendedString.hxx> |
94708556 |
41 | #include <OSD_OpenFile.hxx> |
692613e5 |
42 | #include <fstream> |
a096a7a5 |
43 | #include <algorithm> |
692613e5 |
44 | |
f5f4ebd0 |
45 | IMPLEMENT_STANDARD_RTTIEXT(Image_AlienPixMap,Image_PixMap) |
46 | |
692613e5 |
47 | namespace |
48 | { |
a975e06e |
49 | #ifdef HAVE_FREEIMAGE |
dc858f4c |
50 | static Image_Format convertFromFreeFormat (FREE_IMAGE_TYPE theFormatFI, |
51 | FREE_IMAGE_COLOR_TYPE theColorTypeFI, |
52 | unsigned theBitsPerPixel) |
692613e5 |
53 | { |
54 | switch (theFormatFI) |
55 | { |
dc858f4c |
56 | case FIT_RGBF: return Image_Format_RGBF; |
57 | case FIT_RGBAF: return Image_Format_RGBAF; |
58 | case FIT_FLOAT: return Image_Format_GrayF; |
692613e5 |
59 | case FIT_BITMAP: |
60 | { |
61 | switch (theColorTypeFI) |
62 | { |
63 | case FIC_MINISBLACK: |
64 | { |
dc858f4c |
65 | return Image_Format_Gray; |
692613e5 |
66 | } |
67 | case FIC_RGB: |
68 | { |
69 | if (Image_PixMap::IsBigEndianHost()) |
70 | { |
dc858f4c |
71 | return (theBitsPerPixel == 32) ? Image_Format_RGB32 : Image_Format_RGB; |
692613e5 |
72 | } |
73 | else |
74 | { |
dc858f4c |
75 | return (theBitsPerPixel == 32) ? Image_Format_BGR32 : Image_Format_BGR; |
692613e5 |
76 | } |
77 | } |
78 | case FIC_RGBALPHA: |
79 | { |
dc858f4c |
80 | return Image_PixMap::IsBigEndianHost() ? Image_Format_RGBA : Image_Format_BGRA; |
692613e5 |
81 | } |
82 | default: |
dc858f4c |
83 | return Image_Format_UNKNOWN; |
692613e5 |
84 | } |
85 | } |
86 | default: |
dc858f4c |
87 | return Image_Format_UNKNOWN; |
692613e5 |
88 | } |
89 | } |
90 | |
dc858f4c |
91 | static FREE_IMAGE_TYPE convertToFreeFormat (Image_Format theFormat) |
692613e5 |
92 | { |
93 | switch (theFormat) |
94 | { |
dc858f4c |
95 | case Image_Format_GrayF: |
96 | case Image_Format_AlphaF: |
692613e5 |
97 | return FIT_FLOAT; |
dc858f4c |
98 | case Image_Format_RGBAF: |
692613e5 |
99 | return FIT_RGBAF; |
dc858f4c |
100 | case Image_Format_RGBF: |
692613e5 |
101 | return FIT_RGBF; |
dc858f4c |
102 | case Image_Format_RGBA: |
103 | case Image_Format_BGRA: |
104 | case Image_Format_RGB32: |
105 | case Image_Format_BGR32: |
106 | case Image_Format_RGB: |
107 | case Image_Format_BGR: |
108 | case Image_Format_Gray: |
109 | case Image_Format_Alpha: |
692613e5 |
110 | return FIT_BITMAP; |
111 | default: |
112 | return FIT_UNKNOWN; |
113 | } |
114 | } |
88b12b7c |
115 | |
116 | //! Wrapper for accessing C++ stream from FreeImage. |
117 | class Image_FreeImageStream |
118 | { |
119 | public: |
120 | //! Construct wrapper over input stream. |
121 | Image_FreeImageStream (std::istream& theStream) |
122 | : myIStream (&theStream), myOStream (NULL), myInitPos (theStream.tellg()) {} |
123 | |
124 | //! Get io object. |
125 | FreeImageIO GetFiIO() const |
126 | { |
127 | FreeImageIO anIo; |
128 | memset (&anIo, 0, sizeof(anIo)); |
129 | if (myIStream != NULL) |
130 | { |
131 | anIo.read_proc = readProc; |
132 | anIo.seek_proc = seekProc; |
133 | anIo.tell_proc = tellProc; |
134 | } |
135 | if (myOStream != NULL) |
136 | { |
137 | anIo.write_proc = writeProc; |
138 | } |
139 | return anIo; |
140 | } |
141 | public: |
142 | //! Simulate fread(). |
143 | static unsigned int DLL_CALLCONV readProc (void* theBuffer, unsigned int theSize, unsigned int theCount, fi_handle theHandle) |
144 | { |
145 | Image_FreeImageStream* aThis = (Image_FreeImageStream* )theHandle; |
146 | if (aThis->myIStream == NULL) |
147 | { |
148 | return 0; |
149 | } |
150 | |
151 | if (!aThis->myIStream->read ((char* )theBuffer, std::streamsize(theSize) * std::streamsize(theCount))) |
152 | { |
153 | //aThis->myIStream->clear(); |
154 | } |
155 | const std::streamsize aNbRead = aThis->myIStream->gcount(); |
156 | return (unsigned int )(aNbRead / theSize); |
157 | } |
158 | |
159 | //! Simulate fwrite(). |
160 | static unsigned int DLL_CALLCONV writeProc (void* theBuffer, unsigned int theSize, unsigned int theCount, fi_handle theHandle) |
161 | { |
162 | Image_FreeImageStream* aThis = (Image_FreeImageStream* )theHandle; |
163 | if (aThis->myOStream != NULL |
164 | && aThis->myOStream->write ((const char* )theBuffer, std::streamsize(theSize) * std::streamsize(theCount))) |
165 | { |
166 | return theCount; |
167 | } |
168 | return 0; |
169 | } |
170 | |
171 | //! Simulate fseek(). |
172 | static int DLL_CALLCONV seekProc (fi_handle theHandle, long theOffset, int theOrigin) |
173 | { |
174 | Image_FreeImageStream* aThis = (Image_FreeImageStream* )theHandle; |
175 | if (aThis->myIStream == NULL) |
176 | { |
177 | return -1; |
178 | } |
179 | |
180 | bool isSeekDone = false; |
181 | switch (theOrigin) |
182 | { |
183 | case SEEK_SET: |
184 | if (aThis->myIStream->seekg ((std::streamoff )aThis->myInitPos + theOffset, std::ios::beg)) |
185 | { |
186 | isSeekDone = true; |
187 | } |
188 | break; |
189 | case SEEK_CUR: |
190 | if (aThis->myIStream->seekg (theOffset, std::ios::cur)) |
191 | { |
192 | isSeekDone = true; |
193 | } |
194 | break; |
195 | case SEEK_END: |
196 | if (aThis->myIStream->seekg (theOffset, std::ios::end)) |
197 | { |
198 | isSeekDone = true; |
199 | } |
200 | break; |
201 | } |
202 | return isSeekDone ? 0 : -1; |
203 | } |
204 | |
205 | //! Simulate ftell(). |
206 | static long DLL_CALLCONV tellProc (fi_handle theHandle) |
207 | { |
208 | Image_FreeImageStream* aThis = (Image_FreeImageStream* )theHandle; |
209 | const long aPos = aThis->myIStream != NULL ? (long )(aThis->myIStream->tellg() - aThis->myInitPos) : 0; |
210 | return aPos; |
211 | } |
212 | private: |
213 | std::istream* myIStream; |
214 | std::ostream* myOStream; |
215 | std::streampos myInitPos; |
216 | }; |
217 | |
a975e06e |
218 | #elif defined(HAVE_WINCODEC) |
692613e5 |
219 | |
a975e06e |
220 | //! Return a zero GUID |
221 | static GUID getNullGuid() |
222 | { |
223 | GUID aGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; |
224 | return aGuid; |
225 | } |
226 | |
227 | //! Sentry over IUnknown pointer. |
228 | template<class T> class Image_ComPtr |
229 | { |
230 | public: |
231 | //! Empty constructor. |
232 | Image_ComPtr() |
233 | : myPtr (NULL) {} |
234 | |
235 | //! Destructor. |
236 | ~Image_ComPtr() |
237 | { |
238 | Nullify(); |
239 | } |
240 | |
241 | //! Return TRUE if pointer is NULL. |
242 | bool IsNull() const { return myPtr == NULL; } |
243 | |
244 | //! Release the pointer. |
245 | void Nullify() |
246 | { |
247 | if (myPtr != NULL) |
248 | { |
249 | myPtr->Release(); |
250 | myPtr = NULL; |
251 | } |
252 | } |
253 | |
254 | //! Return pointer for initialization. |
255 | T*& ChangePtr() |
256 | { |
257 | Standard_ASSERT_RAISE (myPtr == NULL, "Pointer cannot be initialized twice!"); |
258 | return myPtr; |
259 | } |
260 | |
261 | //! Return pointer. |
262 | T* get() { return myPtr; } |
263 | |
264 | //! Return pointer. |
265 | T* operator->() { return get(); } |
266 | |
267 | //! Cast handle to contained type |
268 | T& operator*() { return *get(); } |
269 | |
270 | private: |
271 | T* myPtr; |
272 | }; |
273 | |
274 | //! Convert WIC GUID to Image_Format. |
275 | static Image_Format convertFromWicFormat (const WICPixelFormatGUID& theFormat) |
276 | { |
277 | if (theFormat == GUID_WICPixelFormat32bppBGRA) |
278 | { |
279 | return Image_Format_BGRA; |
280 | } |
281 | else if (theFormat == GUID_WICPixelFormat32bppBGR) |
282 | { |
283 | return Image_Format_BGR32; |
284 | } |
285 | else if (theFormat == GUID_WICPixelFormat24bppRGB) |
286 | { |
287 | return Image_Format_RGB; |
288 | } |
289 | else if (theFormat == GUID_WICPixelFormat24bppBGR) |
290 | { |
291 | return Image_Format_BGR; |
292 | } |
293 | else if (theFormat == GUID_WICPixelFormat8bppGray) |
294 | { |
295 | return Image_Format_Gray; |
296 | } |
297 | return Image_Format_UNKNOWN; |
298 | } |
299 | |
300 | //! Convert Image_Format to WIC GUID. |
301 | static WICPixelFormatGUID convertToWicFormat (Image_Format theFormat) |
302 | { |
303 | switch (theFormat) |
304 | { |
305 | case Image_Format_BGRA: return GUID_WICPixelFormat32bppBGRA; |
306 | case Image_Format_BGR32: return GUID_WICPixelFormat32bppBGR; |
307 | case Image_Format_RGB: return GUID_WICPixelFormat24bppRGB; |
308 | case Image_Format_BGR: return GUID_WICPixelFormat24bppBGR; |
309 | case Image_Format_Gray: return GUID_WICPixelFormat8bppGray; |
310 | case Image_Format_Alpha: return GUID_WICPixelFormat8bppGray; // GUID_WICPixelFormat8bppAlpha |
311 | case Image_Format_GrayF: // GUID_WICPixelFormat32bppGrayFloat |
312 | case Image_Format_AlphaF: |
313 | case Image_Format_RGBAF: // GUID_WICPixelFormat128bppRGBAFloat |
314 | case Image_Format_RGBF: // GUID_WICPixelFormat96bppRGBFloat |
315 | case Image_Format_RGBA: // GUID_WICPixelFormat32bppRGBA |
316 | case Image_Format_RGB32: // GUID_WICPixelFormat32bppRGB |
317 | default: |
318 | return getNullGuid(); |
319 | } |
320 | } |
321 | |
322 | #endif |
323 | } |
692613e5 |
324 | |
325 | // ======================================================================= |
326 | // function : Image_AlienPixMap |
327 | // purpose : |
328 | // ======================================================================= |
329 | Image_AlienPixMap::Image_AlienPixMap() |
330 | : myLibImage (NULL) |
331 | { |
332 | SetTopDown (false); |
333 | } |
334 | |
335 | // ======================================================================= |
336 | // function : ~Image_AlienPixMap |
337 | // purpose : |
338 | // ======================================================================= |
339 | Image_AlienPixMap::~Image_AlienPixMap() |
340 | { |
341 | Clear(); |
342 | } |
343 | |
344 | // ======================================================================= |
345 | // function : InitWrapper |
346 | // purpose : |
347 | // ======================================================================= |
dc858f4c |
348 | bool Image_AlienPixMap::InitWrapper (Image_Format, |
35e08fe8 |
349 | Standard_Byte*, |
350 | const Standard_Size, |
351 | const Standard_Size, |
352 | const Standard_Size) |
692613e5 |
353 | { |
354 | Clear(); |
355 | return false; |
356 | } |
357 | |
358 | // ======================================================================= |
359 | // function : InitTrash |
360 | // purpose : |
361 | // ======================================================================= |
498ce76b |
362 | #ifdef HAVE_FREEIMAGE |
dc858f4c |
363 | bool Image_AlienPixMap::InitTrash (Image_Format thePixelFormat, |
692613e5 |
364 | const Standard_Size theSizeX, |
365 | const Standard_Size theSizeY, |
498ce76b |
366 | const Standard_Size /*theSizeRowBytes*/) |
692613e5 |
367 | { |
368 | Clear(); |
692613e5 |
369 | FREE_IMAGE_TYPE aFormatFI = convertToFreeFormat (thePixelFormat); |
370 | int aBitsPerPixel = (int )Image_PixMap::SizePixelBytes (thePixelFormat) * 8; |
371 | if (aFormatFI == FIT_UNKNOWN) |
372 | { |
373 | aFormatFI = FIT_BITMAP; |
374 | aBitsPerPixel = 24; |
375 | } |
376 | |
377 | FIBITMAP* anImage = FreeImage_AllocateT (aFormatFI, (int )theSizeX, (int )theSizeY, aBitsPerPixel); |
dc858f4c |
378 | Image_Format aFormat = convertFromFreeFormat (FreeImage_GetImageType(anImage), |
379 | FreeImage_GetColorType(anImage), |
380 | FreeImage_GetBPP (anImage)); |
381 | if (thePixelFormat == Image_Format_BGR32 |
382 | || thePixelFormat == Image_Format_RGB32) |
692613e5 |
383 | { |
384 | //FreeImage_SetTransparent (anImage, FALSE); |
dc858f4c |
385 | aFormat = (aFormat == Image_Format_BGRA) ? Image_Format_BGR32 : Image_Format_RGB32; |
692613e5 |
386 | } |
387 | |
388 | Image_PixMap::InitWrapper (aFormat, FreeImage_GetBits (anImage), |
389 | FreeImage_GetWidth (anImage), FreeImage_GetHeight (anImage), FreeImage_GetPitch (anImage)); |
390 | SetTopDown (false); |
391 | |
392 | // assign image after wrapper initialization (virtual Clear() called inside) |
393 | myLibImage = anImage; |
394 | return true; |
498ce76b |
395 | } |
a975e06e |
396 | #elif defined(HAVE_WINCODEC) |
397 | bool Image_AlienPixMap::InitTrash (Image_Format thePixelFormat, |
398 | const Standard_Size theSizeX, |
399 | const Standard_Size theSizeY, |
400 | const Standard_Size theSizeRowBytes) |
401 | { |
402 | Clear(); |
403 | Image_Format aFormat = thePixelFormat; |
404 | switch (aFormat) |
405 | { |
406 | case Image_Format_RGB: |
407 | aFormat = Image_Format_BGR; |
408 | break; |
409 | case Image_Format_RGB32: |
410 | aFormat = Image_Format_BGR32; |
411 | break; |
412 | case Image_Format_RGBA: |
413 | aFormat = Image_Format_BGRA; |
414 | break; |
415 | default: |
416 | break; |
417 | } |
418 | |
419 | if (!Image_PixMap::InitTrash (aFormat, theSizeX, theSizeY, theSizeRowBytes)) |
420 | { |
421 | return false; |
422 | } |
423 | SetTopDown (true); |
424 | return true; |
425 | } |
692613e5 |
426 | #else |
dc858f4c |
427 | bool Image_AlienPixMap::InitTrash (Image_Format thePixelFormat, |
498ce76b |
428 | const Standard_Size theSizeX, |
429 | const Standard_Size theSizeY, |
430 | const Standard_Size theSizeRowBytes) |
431 | { |
692613e5 |
432 | return Image_PixMap::InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes); |
692613e5 |
433 | } |
498ce76b |
434 | #endif |
692613e5 |
435 | |
436 | // ======================================================================= |
3c3131a0 |
437 | // function : InitCopy |
692613e5 |
438 | // purpose : |
439 | // ======================================================================= |
440 | bool Image_AlienPixMap::InitCopy (const Image_PixMap& theCopy) |
441 | { |
442 | if (&theCopy == this) |
443 | { |
444 | // self-copying disallowed |
445 | return false; |
446 | } |
447 | if (!InitTrash (theCopy.Format(), theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes())) |
448 | { |
449 | return false; |
450 | } |
451 | |
452 | if (myImgFormat == theCopy.Format()) |
453 | { |
ca0c0b11 |
454 | if (SizeRowBytes() == theCopy.SizeRowBytes() |
455 | && TopDownInc() == theCopy.TopDownInc()) |
692613e5 |
456 | { |
457 | // copy with one call |
ca0c0b11 |
458 | memcpy (ChangeData(), theCopy.Data(), std::min (SizeBytes(), theCopy.SizeBytes())); |
692613e5 |
459 | return true; |
460 | } |
461 | |
462 | // copy row-by-row |
ca0c0b11 |
463 | const Standard_Size aRowSizeBytes = std::min (SizeRowBytes(), theCopy.SizeRowBytes()); |
464 | for (Standard_Size aRow = 0; aRow < myData.SizeY; ++aRow) |
692613e5 |
465 | { |
466 | memcpy (ChangeRow (aRow), theCopy.Row (aRow), aRowSizeBytes); |
467 | } |
468 | return true; |
469 | } |
470 | |
471 | // pixel format conversion required |
472 | Clear(); |
473 | return false; |
474 | } |
475 | |
476 | // ======================================================================= |
477 | // function : Clear |
478 | // purpose : |
479 | // ======================================================================= |
ca0c0b11 |
480 | void Image_AlienPixMap::Clear() |
692613e5 |
481 | { |
ca0c0b11 |
482 | Image_PixMap::Clear(); |
692613e5 |
483 | #ifdef HAVE_FREEIMAGE |
484 | if (myLibImage != NULL) |
485 | { |
486 | FreeImage_Unload (myLibImage); |
487 | myLibImage = NULL; |
488 | } |
489 | #endif |
490 | } |
491 | |
88b12b7c |
492 | // ======================================================================= |
493 | // function : IsTopDownDefault |
494 | // purpose : |
495 | // ======================================================================= |
496 | bool Image_AlienPixMap::IsTopDownDefault() |
497 | { |
498 | #ifdef HAVE_FREEIMAGE |
499 | return false; |
500 | #elif defined(HAVE_WINCODEC) |
501 | return true; |
502 | #else |
503 | return false; |
504 | #endif |
505 | } |
506 | |
692613e5 |
507 | // ======================================================================= |
508 | // function : Load |
509 | // purpose : |
510 | // ======================================================================= |
35e08fe8 |
511 | #ifdef HAVE_FREEIMAGE |
88b12b7c |
512 | bool Image_AlienPixMap::Load (const Standard_Byte* theData, |
513 | Standard_Size theLength, |
514 | const TCollection_AsciiString& theImagePath) |
692613e5 |
515 | { |
516 | Clear(); |
7aa1b65c |
517 | |
518 | #ifdef _WIN32 |
a975e06e |
519 | const TCollection_ExtendedString aFileNameW (theImagePath); |
7aa1b65c |
520 | #endif |
88b12b7c |
521 | FREE_IMAGE_FORMAT aFIF = FIF_UNKNOWN; |
522 | FIMEMORY* aFiMem = NULL; |
523 | if (theData != NULL) |
524 | { |
525 | aFiMem = FreeImage_OpenMemory ((BYTE* )theData, (DWORD )theLength); |
526 | aFIF = FreeImage_GetFileTypeFromMemory (aFiMem, 0); |
527 | } |
528 | else |
529 | { |
530 | #ifdef _WIN32 |
531 | aFIF = FreeImage_GetFileTypeU (aFileNameW.ToWideString(), 0); |
532 | #else |
533 | aFIF = FreeImage_GetFileType (theImagePath.ToCString(), 0); |
534 | #endif |
535 | } |
692613e5 |
536 | if (aFIF == FIF_UNKNOWN) |
537 | { |
538 | // no signature? try to guess the file format from the file extension |
539 | aFIF = FreeImage_GetFIFFromFilename (theImagePath.ToCString()); |
540 | } |
541 | if ((aFIF == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading (aFIF)) |
542 | { |
88b12b7c |
543 | ::Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: image '") + theImagePath + "' has unsupported file format.", |
544 | Message_Fail); |
545 | if (aFiMem != NULL) |
546 | { |
547 | FreeImage_CloseMemory (aFiMem); |
548 | } |
692613e5 |
549 | return false; |
550 | } |
551 | |
552 | int aLoadFlags = 0; |
553 | if (aFIF == FIF_GIF) |
554 | { |
555 | // 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading |
556 | aLoadFlags = GIF_PLAYBACK; |
557 | } |
558 | else if (aFIF == FIF_ICO) |
559 | { |
560 | // convert to 32bpp and create an alpha channel from the AND-mask when loading |
561 | aLoadFlags = ICO_MAKEALPHA; |
562 | } |
563 | |
88b12b7c |
564 | FIBITMAP* anImage = NULL; |
565 | if (theData != NULL) |
566 | { |
567 | anImage = FreeImage_LoadFromMemory (aFIF, aFiMem, aLoadFlags); |
568 | FreeImage_CloseMemory (aFiMem); |
569 | aFiMem = NULL; |
570 | } |
571 | else |
572 | { |
573 | #ifdef _WIN32 |
574 | anImage = FreeImage_LoadU (aFIF, aFileNameW.ToWideString(), aLoadFlags); |
575 | #else |
576 | anImage = FreeImage_Load (aFIF, theImagePath.ToCString(), aLoadFlags); |
577 | #endif |
578 | } |
692613e5 |
579 | if (anImage == NULL) |
580 | { |
0c015ee2 |
581 | TCollection_AsciiString aMessage = "Error: image file '"; |
582 | aMessage.AssignCat (theImagePath); |
583 | aMessage.AssignCat ("' is missing or invalid."); |
584 | ::Message::DefaultMessenger()->Send (aMessage, Message_Fail); |
692613e5 |
585 | return false; |
586 | } |
587 | |
dc858f4c |
588 | Image_Format aFormat = convertFromFreeFormat (FreeImage_GetImageType(anImage), |
589 | FreeImage_GetColorType(anImage), |
590 | FreeImage_GetBPP (anImage)); |
591 | if (aFormat == Image_Format_UNKNOWN) |
692613e5 |
592 | { |
593 | //anImage = FreeImage_ConvertTo24Bits (anImage); |
88b12b7c |
594 | ::Message::DefaultMessenger()->Send ( TCollection_AsciiString ("Error: image '") + theImagePath + "' has unsupported pixel format.", |
595 | Message_Fail); |
692613e5 |
596 | return false; |
597 | } |
598 | |
599 | Image_PixMap::InitWrapper (aFormat, FreeImage_GetBits (anImage), |
600 | FreeImage_GetWidth (anImage), FreeImage_GetHeight (anImage), FreeImage_GetPitch (anImage)); |
601 | SetTopDown (false); |
602 | |
603 | // assign image after wrapper initialization (virtual Clear() called inside) |
604 | myLibImage = anImage; |
605 | return true; |
35e08fe8 |
606 | } |
88b12b7c |
607 | |
608 | bool Image_AlienPixMap::Load (std::istream& theStream, |
609 | const TCollection_AsciiString& theFileName) |
610 | { |
611 | Clear(); |
612 | |
613 | Image_FreeImageStream aStream (theStream); |
614 | FreeImageIO aFiIO = aStream.GetFiIO(); |
615 | |
616 | FREE_IMAGE_FORMAT aFIF = FreeImage_GetFileTypeFromHandle (&aFiIO, &aStream, 0); |
617 | if (aFIF == FIF_UNKNOWN) |
618 | { |
619 | // no signature? try to guess the file format from the file extension |
620 | aFIF = FreeImage_GetFIFFromFilename (theFileName.ToCString()); |
621 | } |
622 | if ((aFIF == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading (aFIF)) |
623 | { |
624 | ::Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: image stream '") + theFileName + "' has unsupported file format.", |
625 | Message_Fail); |
626 | return false; |
627 | } |
628 | |
629 | int aLoadFlags = 0; |
630 | if (aFIF == FIF_GIF) |
631 | { |
632 | // 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading |
633 | aLoadFlags = GIF_PLAYBACK; |
634 | } |
635 | else if (aFIF == FIF_ICO) |
636 | { |
637 | // convert to 32bpp and create an alpha channel from the AND-mask when loading |
638 | aLoadFlags = ICO_MAKEALPHA; |
639 | } |
640 | |
641 | FIBITMAP* anImage = FreeImage_LoadFromHandle (aFIF, &aFiIO, &aStream, aLoadFlags); |
642 | if (anImage == NULL) |
643 | { |
644 | ::Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: image stream '") + theFileName + "' is missing or invalid.", |
645 | Message_Fail); |
646 | return false; |
647 | } |
648 | |
649 | Image_Format aFormat = convertFromFreeFormat (FreeImage_GetImageType(anImage), |
650 | FreeImage_GetColorType(anImage), |
651 | FreeImage_GetBPP (anImage)); |
652 | if (aFormat == Image_Format_UNKNOWN) |
653 | { |
654 | ::Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: image stream '") + theFileName + "' has unsupported pixel format.", |
655 | Message_Fail); |
656 | return false; |
657 | } |
658 | |
659 | Image_PixMap::InitWrapper (aFormat, FreeImage_GetBits (anImage), |
660 | FreeImage_GetWidth (anImage), FreeImage_GetHeight (anImage), FreeImage_GetPitch (anImage)); |
661 | SetTopDown (false); |
662 | |
663 | // assign image after wrapper initialization (virtual Clear() called inside) |
664 | myLibImage = anImage; |
665 | return true; |
666 | } |
667 | |
a975e06e |
668 | #elif defined(HAVE_WINCODEC) |
88b12b7c |
669 | bool Image_AlienPixMap::Load (const Standard_Byte* theData, |
670 | Standard_Size theLength, |
671 | const TCollection_AsciiString& theFileName) |
a975e06e |
672 | { |
673 | Clear(); |
674 | |
88b12b7c |
675 | Image_ComPtr<IWICImagingFactory> aWicImgFactory; |
a975e06e |
676 | CoInitializeEx (NULL, COINIT_MULTITHREADED); |
88b12b7c |
677 | if (CoCreateInstance (CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&aWicImgFactory.ChangePtr())) != S_OK) |
a975e06e |
678 | { |
679 | Message::DefaultMessenger()->Send ("Error: cannot initialize WIC Imaging Factory", Message_Fail); |
680 | return false; |
681 | } |
682 | |
683 | Image_ComPtr<IWICBitmapDecoder> aWicDecoder; |
88b12b7c |
684 | Image_ComPtr<IWICStream> aWicStream; |
685 | if (theData != NULL) |
a975e06e |
686 | { |
88b12b7c |
687 | if (aWicImgFactory->CreateStream (&aWicStream.ChangePtr()) != S_OK |
688 | || aWicStream->InitializeFromMemory ((BYTE* )theData, (DWORD )theLength) != S_OK) |
689 | { |
690 | Message::DefaultMessenger()->Send ("Error: cannot initialize WIC Stream", Message_Fail); |
691 | return false; |
692 | } |
693 | if (aWicImgFactory->CreateDecoderFromStream (aWicStream.get(), NULL, WICDecodeMetadataCacheOnDemand, &aWicDecoder.ChangePtr()) != S_OK) |
694 | { |
695 | Message::DefaultMessenger()->Send ("Error: cannot create WIC Image Decoder", Message_Fail); |
696 | return false; |
697 | } |
698 | } |
699 | else |
700 | { |
701 | const TCollection_ExtendedString aFileNameW (theFileName); |
702 | if (aWicImgFactory->CreateDecoderFromFilename (aFileNameW.ToWideString(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &aWicDecoder.ChangePtr()) != S_OK) |
703 | { |
704 | Message::DefaultMessenger()->Send ("Error: cannot create WIC Image Decoder", Message_Fail); |
705 | return false; |
706 | } |
a975e06e |
707 | } |
708 | |
709 | UINT aFrameCount = 0, aFrameSizeX = 0, aFrameSizeY = 0; |
710 | WICPixelFormatGUID aWicPixelFormat = getNullGuid(); |
711 | Image_ComPtr<IWICBitmapFrameDecode> aWicFrameDecode; |
712 | if (aWicDecoder->GetFrameCount (&aFrameCount) != S_OK |
713 | || aFrameCount < 1 |
714 | || aWicDecoder->GetFrame (0, &aWicFrameDecode.ChangePtr()) != S_OK |
715 | || aWicFrameDecode->GetSize (&aFrameSizeX, &aFrameSizeY) != S_OK |
716 | || aWicFrameDecode->GetPixelFormat (&aWicPixelFormat)) |
717 | { |
718 | Message::DefaultMessenger()->Send ("Error: cannot get WIC Image Frame", Message_Fail); |
719 | return false; |
720 | } |
721 | |
722 | Image_ComPtr<IWICFormatConverter> aWicConvertedFrame; |
723 | Image_Format aPixelFormat = convertFromWicFormat (aWicPixelFormat); |
724 | if (aPixelFormat == Image_Format_UNKNOWN) |
725 | { |
726 | aPixelFormat = Image_Format_RGB; |
727 | if (aWicImgFactory->CreateFormatConverter (&aWicConvertedFrame.ChangePtr()) != S_OK |
728 | || aWicConvertedFrame->Initialize (aWicFrameDecode.get(), convertToWicFormat (aPixelFormat), WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom) != S_OK) |
729 | { |
730 | Message::DefaultMessenger()->Send ("Error: cannot convert WIC Image Frame to RGB format", Message_Fail); |
731 | return false; |
732 | } |
733 | aWicFrameDecode.Nullify(); |
734 | } |
735 | |
736 | if (!Image_PixMap::InitTrash (aPixelFormat, aFrameSizeX, aFrameSizeY)) |
737 | { |
738 | Message::DefaultMessenger()->Send ("Error: cannot initialize memory for image", Message_Fail); |
739 | return false; |
740 | } |
741 | |
742 | IWICBitmapSource* aWicSrc = aWicFrameDecode.get(); |
743 | if(!aWicConvertedFrame.IsNull()) |
744 | { |
745 | aWicSrc = aWicConvertedFrame.get(); |
746 | } |
747 | if (aWicSrc->CopyPixels (NULL, (UINT )SizeRowBytes(), (UINT )SizeBytes(), ChangeData()) != S_OK) |
748 | { |
749 | Message::DefaultMessenger()->Send ("Error: cannot copy pixels from WIC Image", Message_Fail); |
750 | return false; |
751 | } |
752 | SetTopDown (true); |
753 | return true; |
754 | } |
88b12b7c |
755 | bool Image_AlienPixMap::Load (std::istream& theStream, |
756 | const TCollection_AsciiString& theFilePath) |
757 | { |
758 | Clear(); |
759 | |
760 | // fallback copying stream data into transient buffer |
761 | const std::streamoff aStart = theStream.tellg(); |
762 | theStream.seekg (0, std::ios::end); |
763 | const Standard_Integer aLen = Standard_Integer(theStream.tellg() - aStart); |
764 | theStream.seekg (aStart); |
765 | if (aLen <= 0) |
766 | { |
767 | Message::DefaultMessenger()->Send ("Error: empty stream", Message_Fail); |
768 | return false; |
769 | } |
770 | |
771 | NCollection_Array1<Standard_Byte> aBuff (1, aLen); |
772 | if (!theStream.read ((char* )&aBuff.ChangeFirst(), aBuff.Size())) |
773 | { |
774 | Message::DefaultMessenger()->Send ("Error: unable to read stream", Message_Fail); |
775 | return false; |
776 | } |
777 | |
778 | return Load (&aBuff.ChangeFirst(), aBuff.Size(), theFilePath); |
779 | } |
692613e5 |
780 | #else |
88b12b7c |
781 | bool Image_AlienPixMap::Load (std::istream& , |
782 | const TCollection_AsciiString& ) |
783 | { |
784 | Clear(); |
785 | Message::DefaultMessenger()->Send ("Error: no image library available", Message_Fail); |
786 | return false; |
787 | } |
788 | bool Image_AlienPixMap::Load (const Standard_Byte* , |
789 | Standard_Size , |
790 | const TCollection_AsciiString& ) |
35e08fe8 |
791 | { |
792 | Clear(); |
88b12b7c |
793 | Message::DefaultMessenger()->Send ("Error: no image library available", Message_Fail); |
692613e5 |
794 | return false; |
692613e5 |
795 | } |
35e08fe8 |
796 | #endif |
692613e5 |
797 | |
798 | // ======================================================================= |
799 | // function : savePPM |
800 | // purpose : |
801 | // ======================================================================= |
802 | bool Image_AlienPixMap::savePPM (const TCollection_AsciiString& theFileName) const |
803 | { |
804 | if (IsEmpty()) |
805 | { |
806 | return false; |
807 | } |
808 | |
809 | // Open file |
94708556 |
810 | FILE* aFile = OSD_OpenFile (theFileName.ToCString(), "wb"); |
692613e5 |
811 | if (aFile == NULL) |
812 | { |
813 | return false; |
814 | } |
815 | |
816 | // Write header |
817 | fprintf (aFile, "P6\n%d %d\n255\n", (int )SizeX(), (int )SizeY()); |
818 | fprintf (aFile, "# Image stored by OpenCASCADE framework in linear RGB colorspace\n"); |
819 | |
820 | // Write pixel data |
692613e5 |
821 | Standard_Byte aByte; |
822 | for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow) |
823 | { |
a7b491fc |
824 | for (Standard_Size aCol = 0; aCol < SizeX(); ++aCol) |
692613e5 |
825 | { |
826 | // extremely SLOW but universal (implemented for all supported pixel formats) |
e958a649 |
827 | const Quantity_ColorRGBA aColor = PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow); |
828 | aByte = Standard_Byte(aColor.GetRGB().Red() * 255.0); fwrite (&aByte, 1, 1, aFile); |
829 | aByte = Standard_Byte(aColor.GetRGB().Green() * 255.0); fwrite (&aByte, 1, 1, aFile); |
830 | aByte = Standard_Byte(aColor.GetRGB().Blue() * 255.0); fwrite (&aByte, 1, 1, aFile); |
692613e5 |
831 | } |
832 | } |
833 | |
834 | // Close file |
835 | fclose (aFile); |
836 | return true; |
837 | } |
838 | |
839 | // ======================================================================= |
840 | // function : Save |
841 | // purpose : |
842 | // ======================================================================= |
843 | bool Image_AlienPixMap::Save (const TCollection_AsciiString& theFileName) |
844 | { |
845 | #ifdef HAVE_FREEIMAGE |
846 | if (myLibImage == NULL) |
847 | { |
848 | return false; |
849 | } |
850 | |
7aa1b65c |
851 | #ifdef _WIN32 |
852 | const TCollection_ExtendedString aFileNameW (theFileName.ToCString(), Standard_True); |
fb0b0531 |
853 | FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilenameU (aFileNameW.ToWideString()); |
7aa1b65c |
854 | #else |
692613e5 |
855 | FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilename (theFileName.ToCString()); |
7aa1b65c |
856 | #endif |
692613e5 |
857 | if (anImageFormat == FIF_UNKNOWN) |
858 | { |
0797d9d3 |
859 | #ifdef OCCT_DEBUG |
692613e5 |
860 | std::cerr << "Image_PixMap, image format doesn't supported!\n"; |
63c629aa |
861 | #endif |
692613e5 |
862 | return false; |
863 | } |
864 | |
865 | if (IsTopDown()) |
866 | { |
867 | FreeImage_FlipVertical (myLibImage); |
868 | SetTopDown (false); |
869 | } |
870 | |
dc858f4c |
871 | // FreeImage doesn't provide flexible format conversion API |
872 | // so we should perform multiple conversions in some cases! |
692613e5 |
873 | FIBITMAP* anImageToDump = myLibImage; |
874 | switch (anImageFormat) |
875 | { |
876 | case FIF_PNG: |
877 | case FIF_BMP: |
878 | { |
dc858f4c |
879 | if (Format() == Image_Format_BGR32 |
880 | || Format() == Image_Format_RGB32) |
692613e5 |
881 | { |
882 | // stupid FreeImage treats reserved byte as alpha if some bytes not set to 0xFF |
692613e5 |
883 | for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow) |
884 | { |
885 | for (Standard_Size aCol = 0; aCol < SizeX(); ++aCol) |
886 | { |
ca0c0b11 |
887 | myData.ChangeValue (aRow, aCol)[3] = 0xFF; |
692613e5 |
888 | } |
889 | } |
890 | } |
891 | else if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP) |
892 | { |
893 | anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_BITMAP); |
894 | } |
895 | break; |
896 | } |
897 | case FIF_GIF: |
898 | { |
899 | FIBITMAP* aTmpBitmap = myLibImage; |
900 | if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP) |
901 | { |
902 | aTmpBitmap = FreeImage_ConvertToType (myLibImage, FIT_BITMAP); |
903 | if (aTmpBitmap == NULL) |
904 | { |
905 | return false; |
906 | } |
907 | } |
908 | |
909 | if (FreeImage_GetBPP (aTmpBitmap) != 24) |
910 | { |
911 | FIBITMAP* aTmpBitmap24 = FreeImage_ConvertTo24Bits (aTmpBitmap); |
912 | if (aTmpBitmap != myLibImage) |
913 | { |
914 | FreeImage_Unload (aTmpBitmap); |
915 | } |
916 | if (aTmpBitmap24 == NULL) |
917 | { |
918 | return false; |
919 | } |
920 | aTmpBitmap = aTmpBitmap24; |
921 | } |
922 | |
dc858f4c |
923 | // need conversion to image with palette (requires 24bit bitmap) |
692613e5 |
924 | anImageToDump = FreeImage_ColorQuantize (aTmpBitmap, FIQ_NNQUANT); |
925 | if (aTmpBitmap != myLibImage) |
926 | { |
927 | FreeImage_Unload (aTmpBitmap); |
928 | } |
929 | break; |
930 | } |
38d90bb3 |
931 | case FIF_HDR: |
692613e5 |
932 | case FIF_EXR: |
933 | { |
dc858f4c |
934 | if (Format() == Image_Format_Gray |
935 | || Format() == Image_Format_Alpha) |
692613e5 |
936 | { |
937 | anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_FLOAT); |
938 | } |
dc858f4c |
939 | else if (Format() == Image_Format_RGBA |
940 | || Format() == Image_Format_BGRA) |
692613e5 |
941 | { |
942 | anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_RGBAF); |
943 | } |
944 | else |
945 | { |
946 | FREE_IMAGE_TYPE aImgTypeFI = FreeImage_GetImageType (myLibImage); |
947 | if (aImgTypeFI != FIT_RGBF |
948 | && aImgTypeFI != FIT_RGBAF |
949 | && aImgTypeFI != FIT_FLOAT) |
950 | { |
951 | anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_RGBF); |
952 | } |
953 | } |
954 | break; |
955 | } |
956 | default: |
957 | { |
958 | if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP) |
959 | { |
960 | anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_BITMAP); |
961 | if (anImageToDump == NULL) |
962 | { |
963 | return false; |
964 | } |
965 | } |
966 | |
967 | if (FreeImage_GetBPP (anImageToDump) != 24) |
968 | { |
969 | FIBITMAP* aTmpBitmap24 = FreeImage_ConvertTo24Bits (anImageToDump); |
970 | if (anImageToDump != myLibImage) |
971 | { |
972 | FreeImage_Unload (anImageToDump); |
973 | } |
974 | if (aTmpBitmap24 == NULL) |
975 | { |
976 | return false; |
977 | } |
978 | anImageToDump = aTmpBitmap24; |
979 | } |
980 | break; |
981 | } |
982 | } |
983 | |
984 | if (anImageToDump == NULL) |
985 | { |
986 | return false; |
987 | } |
988 | |
7aa1b65c |
989 | #ifdef _WIN32 |
fb0b0531 |
990 | bool isSaved = (FreeImage_SaveU (anImageFormat, anImageToDump, aFileNameW.ToWideString()) != FALSE); |
7aa1b65c |
991 | #else |
992 | bool isSaved = (FreeImage_Save (anImageFormat, anImageToDump, theFileName.ToCString()) != FALSE); |
993 | #endif |
692613e5 |
994 | if (anImageToDump != myLibImage) |
995 | { |
996 | FreeImage_Unload (anImageToDump); |
997 | } |
998 | return isSaved; |
a975e06e |
999 | |
1000 | #elif defined(HAVE_WINCODEC) |
1001 | |
1002 | TCollection_AsciiString aFileNameLower = theFileName; |
1003 | aFileNameLower.LowerCase(); |
1004 | GUID aFileFormat = getNullGuid(); |
1005 | if (aFileNameLower.EndsWith (".ppm")) |
1006 | { |
1007 | return savePPM (theFileName); |
1008 | } |
1009 | else if (aFileNameLower.EndsWith (".bmp")) |
1010 | { |
1011 | aFileFormat = GUID_ContainerFormatBmp; |
1012 | } |
1013 | else if (aFileNameLower.EndsWith (".png")) |
1014 | { |
1015 | aFileFormat = GUID_ContainerFormatPng; |
1016 | } |
1017 | else if (aFileNameLower.EndsWith (".jpg") |
1018 | || aFileNameLower.EndsWith (".jpeg")) |
1019 | { |
1020 | aFileFormat = GUID_ContainerFormatJpeg; |
1021 | } |
1022 | else if (aFileNameLower.EndsWith (".tiff")) |
1023 | { |
1024 | aFileFormat = GUID_ContainerFormatTiff; |
1025 | } |
1026 | else if (aFileNameLower.EndsWith (".gif")) |
1027 | { |
1028 | aFileFormat = GUID_ContainerFormatGif; |
1029 | } |
1030 | |
1031 | if (aFileFormat == getNullGuid()) |
1032 | { |
1033 | Message::DefaultMessenger()->Send ("Error: unsupported image format", Message_Fail); |
1034 | return false; |
1035 | } |
1036 | |
88b12b7c |
1037 | Image_ComPtr<IWICImagingFactory> aWicImgFactory; |
a975e06e |
1038 | CoInitializeEx (NULL, COINIT_MULTITHREADED); |
88b12b7c |
1039 | if (CoCreateInstance (CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&aWicImgFactory.ChangePtr())) != S_OK) |
a975e06e |
1040 | { |
1041 | Message::DefaultMessenger()->Send ("Error: cannot initialize WIC Imaging Factory", Message_Fail); |
1042 | return false; |
1043 | } |
1044 | |
1045 | Image_ComPtr<IWICStream> aWicFileStream; |
1046 | Image_ComPtr<IWICBitmapEncoder> aWicEncoder; |
1047 | const TCollection_ExtendedString aFileNameW (theFileName); |
1048 | if (aWicImgFactory->CreateStream (&aWicFileStream.ChangePtr()) != S_OK |
1049 | || aWicFileStream->InitializeFromFilename (aFileNameW.ToWideString(), GENERIC_WRITE) != S_OK) |
1050 | { |
1051 | Message::DefaultMessenger()->Send ("Error: cannot create WIC File Stream", Message_Fail); |
1052 | return false; |
1053 | } |
1054 | if (aWicImgFactory->CreateEncoder (aFileFormat, NULL, &aWicEncoder.ChangePtr()) != S_OK |
1055 | || aWicEncoder->Initialize (aWicFileStream.get(), WICBitmapEncoderNoCache) != S_OK) |
1056 | { |
1057 | Message::DefaultMessenger()->Send ("Error: cannot create WIC Encoder", Message_Fail); |
1058 | return false; |
1059 | } |
1060 | |
1061 | const WICPixelFormatGUID aWicPixelFormat = convertToWicFormat (myImgFormat); |
1062 | if (aWicPixelFormat == getNullGuid()) |
1063 | { |
1064 | Message::DefaultMessenger()->Send ("Error: unsupported pixel format", Message_Fail); |
1065 | return false; |
1066 | } |
1067 | |
1068 | WICPixelFormatGUID aWicPixelFormatRes = aWicPixelFormat; |
1069 | Image_ComPtr<IWICBitmapFrameEncode> aWicFrameEncode; |
1070 | if (aWicEncoder->CreateNewFrame (&aWicFrameEncode.ChangePtr(), NULL) != S_OK |
1071 | || aWicFrameEncode->Initialize (NULL) != S_OK |
1072 | || aWicFrameEncode->SetSize ((UINT )SizeX(), (UINT )SizeY()) != S_OK |
1073 | || aWicFrameEncode->SetPixelFormat (&aWicPixelFormatRes) != S_OK) |
1074 | { |
1075 | Message::DefaultMessenger()->Send ("Error: cannot create WIC Frame", Message_Fail); |
1076 | return false; |
1077 | } |
1078 | |
1079 | if (aWicPixelFormatRes != aWicPixelFormat) |
1080 | { |
1081 | Message::DefaultMessenger()->Send ("Error: pixel format is unsupported by image format", Message_Fail); |
1082 | return false; |
1083 | } |
1084 | |
1085 | if (IsTopDown()) |
1086 | { |
1087 | if (aWicFrameEncode->WritePixels ((UINT )SizeY(), (UINT )SizeRowBytes(), (UINT )SizeBytes(), (BYTE* )Data()) != S_OK) |
1088 | { |
1089 | Message::DefaultMessenger()->Send ("Error: cannot write pixels to WIC Frame", Message_Fail); |
1090 | return false; |
1091 | } |
1092 | } |
1093 | else |
1094 | { |
1095 | for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow) |
1096 | { |
1097 | if (aWicFrameEncode->WritePixels (1, (UINT )SizeRowBytes(), (UINT )SizeRowBytes(), (BYTE* )Row (aRow)) != S_OK) |
1098 | { |
1099 | Message::DefaultMessenger()->Send ("Error: cannot write pixels to WIC Frame", Message_Fail); |
1100 | return false; |
1101 | } |
1102 | } |
1103 | } |
1104 | |
1105 | if (aWicFrameEncode->Commit() != S_OK |
1106 | || aWicEncoder->Commit() != S_OK) |
1107 | { |
1108 | Message::DefaultMessenger()->Send ("Error: cannot commit data to WIC Frame", Message_Fail); |
1109 | return false; |
1110 | } |
1111 | if (aWicFileStream->Commit (STGC_DEFAULT) != S_OK) |
1112 | { |
1113 | //Message::DefaultMessenger()->Send ("Error: cannot commit data to WIC File Stream", Message_Fail); |
1114 | //return false; |
1115 | } |
1116 | return true; |
692613e5 |
1117 | #else |
1118 | const Standard_Integer aLen = theFileName.Length(); |
1119 | if ((aLen >= 4) && (theFileName.Value (aLen - 3) == '.') |
29cb310a |
1120 | && strcasecmp( theFileName.ToCString() + aLen - 3, "ppm") == 0 ) |
692613e5 |
1121 | { |
1122 | return savePPM (theFileName); |
1123 | } |
0797d9d3 |
1124 | #ifdef OCCT_DEBUG |
692613e5 |
1125 | std::cerr << "Image_PixMap, no image library available! Image saved in PPM format.\n"; |
63c629aa |
1126 | #endif |
692613e5 |
1127 | return savePPM (theFileName); |
1128 | #endif |
1129 | } |
1130 | |
1131 | // ======================================================================= |
1132 | // function : AdjustGamma |
1133 | // purpose : |
1134 | // ======================================================================= |
7aa1b65c |
1135 | bool Image_AlienPixMap::AdjustGamma (const Standard_Real theGammaCorr) |
692613e5 |
1136 | { |
7aa1b65c |
1137 | #ifdef HAVE_FREEIMAGE |
692613e5 |
1138 | return FreeImage_AdjustGamma (myLibImage, theGammaCorr) != FALSE; |
1139 | #else |
7aa1b65c |
1140 | (void )theGammaCorr; |
1141 | return false; |
35e08fe8 |
1142 | #endif |
7aa1b65c |
1143 | } |