/[projet1]/public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/MultiPage.cpp
Defence Force logotype

Contents of /public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/MultiPage.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (show annotations)
Mon Jul 13 12:20:10 2009 UTC (10 years, 7 months ago) by dbug
File size: 21710 byte(s)
Added some shared libraries (UnitTest++, and FreeImage) to avoid having every single project brings its own libraries.
Ideally people should add them in a way we can upgrade versions without breaking things:
-> public/pc/shared_libraries/library_name/library_version/actuall_content
1 // ==========================================================
2 // Multi-Page functions
3 //
4 // Design and implementation by
5 // - Floris van den Berg (flvdberg@wxs.nl)
6 // - Laurent Rocher (rocherl@club-internet.fr)
7 // - Steve Johnson (steve@parisgroup.net)
8 // - Petr Pytelka (pyta@lightcomp.com)
9 // - Hervé Drolon (drolon@infonie.fr)
10 // - Vadim Alexandrov (vadimalexandrov@users.sourceforge.net
11 // - Martin Dyring-Andersen (mda@spamfighter.com)
12 //
13 // This file is part of FreeImage 3
14 //
15 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
16 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
17 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
18 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
19 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
20 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
21 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
22 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
23 // THIS DISCLAIMER.
24 //
25 // Use at your own risk!
26 // ==========================================================
27
28 #ifdef _MSC_VER
29 #pragma warning (disable : 4786) // identifier was truncated to 'number' characters
30 #endif
31
32 #include "CacheFile.h"
33 #include "FreeImageIO.h"
34 #include "Plugin.h"
35 #include "Utilities.h"
36 #include "FreeImage.h"
37
38 // ----------------------------------------------------------
39
40 enum BlockType { BLOCK_CONTINUEUS, BLOCK_REFERENCE };
41
42 // ----------------------------------------------------------
43
44 struct BlockTypeS {
45 BlockType m_type;
46
47 BlockTypeS(BlockType type) : m_type(type) {
48 }
49 };
50
51 struct BlockContinueus : public BlockTypeS {
52 int m_start;
53 int m_end;
54
55 BlockContinueus(int s, int e) : BlockTypeS(BLOCK_CONTINUEUS),
56 m_start(s),
57 m_end(e) {
58 }
59 };
60
61 struct BlockReference : public BlockTypeS {
62 int m_reference;
63 int m_size;
64
65 BlockReference(int r, int size) : BlockTypeS(BLOCK_REFERENCE),
66 m_reference(r),
67 m_size(size) {
68 }
69 };
70
71 // ----------------------------------------------------------
72
73 typedef std::list<BlockTypeS *> BlockList;
74 typedef std::list<BlockTypeS *>::iterator BlockListIterator;
75
76 // ----------------------------------------------------------
77
78 FI_STRUCT (MULTIBITMAPHEADER) {
79 PluginNode *node;
80 FREE_IMAGE_FORMAT fif;
81 FreeImageIO *io;
82 fi_handle handle;
83 CacheFile *m_cachefile;
84 std::map<FIBITMAP *, int> locked_pages;
85 BOOL changed;
86 int page_count;
87 BlockList m_blocks;
88 char *m_filename;
89 BOOL read_only;
90 FREE_IMAGE_FORMAT cache_fif;
91 int load_flags;
92 };
93
94 // =====================================================================
95 // Internal Multipage functions
96 // =====================================================================
97
98 inline MULTIBITMAPHEADER *
99 FreeImage_GetMultiBitmapHeader(FIMULTIBITMAP *bitmap) {
100 return (MULTIBITMAPHEADER *)bitmap->data;
101 }
102
103 static BlockListIterator DLL_CALLCONV
104 FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int position) {
105 assert(NULL != bitmap);
106
107 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
108
109 // step 1: find the block that matches the given position
110
111 int prev_count = 0;
112 int count = 0;
113 BlockListIterator i;
114 BlockTypeS *current_block = NULL;
115
116 for (i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
117 prev_count = count;
118
119 switch((*i)->m_type) {
120 case BLOCK_CONTINUEUS :
121 count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
122 break;
123
124 case BLOCK_REFERENCE :
125 count++;
126 break;
127 }
128
129 current_block = *i;
130
131 if (count > position)
132 break;
133 }
134
135 // step 2: make sure we found the node. from here it gets a little complicated:
136 // * if the block is there, just return it
137 // * if the block is a series of blocks, split it in max 3 new blocks
138 // and return the splitted block
139
140 if ((current_block) && (count > position)) {
141 switch(current_block->m_type) {
142 case BLOCK_REFERENCE :
143 return i;
144
145 case BLOCK_CONTINUEUS :
146 {
147 BlockContinueus *block = (BlockContinueus *)current_block;
148
149 if (block->m_start != block->m_end) {
150 int item = block->m_start + (position - prev_count);
151
152 // left part
153
154 if (item != block->m_start) {
155 BlockContinueus *block_a = new BlockContinueus(block->m_start, item - 1);
156 header->m_blocks.insert(i, (BlockTypeS *)block_a);
157 }
158
159 // middle part
160
161 BlockContinueus *block_b = new BlockContinueus(item, item);
162 BlockListIterator block_target = header->m_blocks.insert(i, (BlockTypeS *)block_b);
163
164 // right part
165
166 if (item != block->m_end) {
167 BlockContinueus *block_c = new BlockContinueus(item + 1, block->m_end);
168 header->m_blocks.insert(i, (BlockTypeS *)block_c);
169 }
170
171 // remove the old block that was just splitted
172
173 header->m_blocks.remove((BlockTypeS *)block);
174 delete block;
175
176 // return the splitted block
177
178 return block_target;
179 }
180
181 return i;
182 }
183 }
184 }
185 // we should never go here ...
186 assert(false);
187 return header->m_blocks.end();
188 }
189
190 int DLL_CALLCONV
191 FreeImage_InternalGetPageCount(FIMULTIBITMAP *bitmap) {
192 if (bitmap) {
193 if (((MULTIBITMAPHEADER *)bitmap->data)->handle) {
194 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
195
196 header->io->seek_proc(header->handle, 0, SEEK_SET);
197
198 void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
199
200 int page_count = (header->node->m_plugin->pagecount_proc != NULL) ? header->node->m_plugin->pagecount_proc(header->io, header->handle, data) : 1;
201
202 FreeImage_Close(header->node, header->io, header->handle, data);
203
204 return page_count;
205 }
206 }
207
208 return 0;
209 }
210
211 // =====================================================================
212 // Multipage functions
213 // =====================================================================
214
215 FIMULTIBITMAP * DLL_CALLCONV
216 FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) {
217 // retrieve the plugin list to find the node belonging to this plugin
218
219 PluginList *list = FreeImage_GetPluginList();
220
221 if (list) {
222 PluginNode *node = list->FindNodeFromFIF(fif);
223
224 if (node) {
225 FreeImageIO *io = new FreeImageIO;
226
227 if (io) {
228 SetMemoryIO(io);
229
230 FIMULTIBITMAP *bitmap = new FIMULTIBITMAP;
231
232 if (bitmap) {
233 MULTIBITMAPHEADER *header = new MULTIBITMAPHEADER;
234
235 header->m_filename = NULL;
236 header->node = node;
237 header->fif = fif;
238 header->io = io;
239 header->handle = (fi_handle)stream;
240 header->changed = FALSE;
241 header->read_only = TRUE;
242 header->m_cachefile = NULL;
243 header->cache_fif = fif;
244 header->load_flags = flags;
245
246 if (header) {
247 // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
248
249 bitmap->data = header;
250
251 // cache the page count
252
253 header->page_count = FreeImage_InternalGetPageCount(bitmap);
254
255 // allocate a continueus block to describe the bitmap
256
257 header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
258
259 // set up the cache
260
261 return bitmap;
262 }
263
264 return NULL;
265 }
266 }
267
268 delete io;
269 }
270 }
271
272 return NULL;
273 }
274
275 FIMULTIBITMAP * DLL_CALLCONV
276 FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) {
277 // sanity check on the parameters
278
279 if (create_new)
280 read_only = FALSE;
281
282 // retrieve the plugin list to find the node belonging to this plugin
283
284 PluginList *list = FreeImage_GetPluginList();
285
286 if (list) {
287 PluginNode *node = list->FindNodeFromFIF(fif);
288
289 if (node) {
290 FreeImageIO *io = new FreeImageIO;
291
292 if (io) {
293 SetDefaultIO(io);
294
295 BOOL cont = TRUE;
296
297 FILE *handle = NULL;
298
299 if (!create_new) {
300 handle = fopen(filename, "rb");
301
302 if (handle == NULL) {
303 cont = FALSE;
304 }
305 }
306
307 if (cont) {
308 FIMULTIBITMAP *bitmap = new FIMULTIBITMAP;
309
310 if (bitmap) {
311 MULTIBITMAPHEADER *header = new MULTIBITMAPHEADER;
312
313 header->m_filename = new char[strlen(filename) + 1];
314 strcpy(header->m_filename, filename);
315 header->node = node;
316 header->fif = fif;
317 header->io = io;
318 header->handle = handle;
319 header->changed = FALSE;
320 header->read_only = read_only;
321 header->m_cachefile = NULL;
322 header->cache_fif = fif;
323 header->load_flags = flags;
324
325 if (header) {
326 // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
327
328 bitmap->data = header;
329
330 // cache the page count
331
332 header->page_count = FreeImage_InternalGetPageCount(bitmap);
333
334 // allocate a continueus block to describe the bitmap
335
336 if (!create_new)
337 header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
338
339 // set up the cache
340
341 if (!read_only) {
342 char cache_name[256];
343 ReplaceExtension(cache_name, filename, "ficache");
344
345 CacheFile *cache_file = new CacheFile(cache_name, keep_cache_in_memory);
346
347 if (cache_file->open()) {
348 header->m_cachefile = cache_file;
349
350 // return the multibitmap
351
352 return bitmap;
353 }
354
355 delete cache_file;
356 delete header;
357 }
358
359 return bitmap;
360 }
361
362 return NULL;
363 }
364 }
365 }
366
367 delete io;
368 }
369 }
370
371 return NULL;
372 }
373
374 BOOL DLL_CALLCONV
375 FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
376 if (bitmap) {
377 BOOL success = TRUE;
378
379 if (bitmap->data) {
380 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
381
382 if (header->changed) {
383 // open a temp file
384
385 char spool_name[256];
386
387 ReplaceExtension(spool_name, header->m_filename, "fispool");
388
389 // open the spool file and the source file
390
391 FILE *f = fopen(spool_name, "w+b");
392
393 void *data = FreeImage_Open(header->node, header->io, (fi_handle)f, FALSE);
394 void *data_read = NULL;
395
396 if (header->handle) {
397 header->io->seek_proc(header->handle, 0, SEEK_SET);
398
399 data_read = FreeImage_Open(header->node, header->io, header->handle, TRUE);
400 }
401
402 // write all the pages to the temp file
403
404 int count = 0;
405
406 for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) {
407 if (success) {
408 switch((*i)->m_type) {
409 case BLOCK_CONTINUEUS :
410 {
411 BlockContinueus *block = (BlockContinueus *)(*i);
412
413 for (int j = block->m_start; j <= block->m_end; j++) {
414 FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read);
415
416 success = header->node->m_plugin->save_proc(header->io, dib, (fi_handle)f, count, flags, data);
417 count++;
418
419 FreeImage_Unload(dib);
420 }
421
422 break;
423 }
424
425 case BLOCK_REFERENCE :
426 {
427 BlockReference *ref = (BlockReference *)(*i);
428
429 // read the compressed data
430
431 BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE));
432
433 header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size);
434
435 // uncompress the data
436
437 FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size);
438 FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0);
439 FreeImage_CloseMemory(hmem);
440
441 // get rid of the buffer
442 free(compressed_data);
443
444 // save the data
445
446 success = header->node->m_plugin->save_proc(header->io, dib, (fi_handle)f, count, flags, data);
447 count++;
448
449 // unload the dib
450
451 FreeImage_Unload(dib);
452
453 break;
454 }
455 }
456 } else {
457 break;
458 }
459 }
460
461 // close the files
462
463 FreeImage_Close(header->node, header->io, (fi_handle)f, data);
464
465 fclose(f);
466
467 if (header->handle) {
468 FreeImage_Close(header->node, header->io, header->handle, data_read);
469
470 fclose((FILE *)header->handle);
471 }
472
473 if (success) {
474 remove(header->m_filename);
475
476 rename(spool_name, header->m_filename);
477 } else {
478 remove(spool_name);
479 }
480 } else {
481 if (header->handle && header->m_filename) {
482 fclose((FILE *)header->handle);
483 }
484 }
485
486 // clear the blocks list
487
488 for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i)
489 delete *i;
490
491 // flush and dispose the cache
492
493 if (header->m_cachefile) {
494 header->m_cachefile->close();
495
496 delete header->m_cachefile;
497 }
498
499 // delete the last open bitmaps
500
501 while (!header->locked_pages.empty()) {
502 FreeImage_Unload(header->locked_pages.begin()->first);
503
504 header->locked_pages.erase(header->locked_pages.begin()->first);
505 }
506
507 // get rid of the IO structure
508
509 delete header->io;
510
511 // delete the filename
512
513 if(header->m_filename)
514 delete[] header->m_filename;
515
516 // delete the FIMULTIBITMAPHEADER
517
518 delete header;
519 }
520
521 delete bitmap;
522
523 return success;
524 }
525
526 return FALSE;
527 }
528
529 int DLL_CALLCONV
530 FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
531 if (bitmap) {
532 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
533
534 if (header->page_count == -1) {
535 header->page_count = 0;
536
537 for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
538 switch((*i)->m_type) {
539 case BLOCK_CONTINUEUS :
540 header->page_count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
541 break;
542
543 case BLOCK_REFERENCE :
544 header->page_count++;
545 break;
546 }
547 }
548 }
549
550 return header->page_count;
551 }
552
553 return 0;
554 }
555
556 void DLL_CALLCONV
557 FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
558 if ((bitmap) && (data)) {
559 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
560
561 if ((!header->read_only) && (header->locked_pages.empty())) {
562 DWORD compressed_size = 0;
563 BYTE *compressed_data = NULL;
564
565 // compress the bitmap data
566
567 // open a memory handle
568 FIMEMORY *hmem = FreeImage_OpenMemory();
569 // save the file to memory
570 FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0);
571 // get the buffer from the memory stream
572 FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
573
574 // write the compressed data to the cache
575
576 int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
577
578 BlockReference *block = new BlockReference(ref, compressed_size);
579
580 // get rid of the compressed data
581
582 FreeImage_CloseMemory(hmem);
583
584 // add the block
585
586 header->m_blocks.push_back((BlockTypeS *)block);
587 header->changed = TRUE;
588 header->page_count = -1;
589 }
590 }
591 }
592
593 void DLL_CALLCONV
594 FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) {
595 if ((bitmap) && (data)) {
596 if (page < FreeImage_GetPageCount(bitmap)) {
597 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
598
599 if ((!header->read_only) && (header->locked_pages.empty())) {
600 DWORD compressed_size = 0;
601 BYTE *compressed_data = NULL;
602
603 // compress the bitmap data
604
605 // open a memory handle
606 FIMEMORY *hmem = FreeImage_OpenMemory();
607 // save the file to memory
608 FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0);
609 // get the buffer from the memory stream
610 FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
611
612 // write the compressed data to the cache
613
614 int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
615
616 // add a block
617
618 if (page > 0) {
619 BlockListIterator block_source = FreeImage_FindBlock(bitmap, page);
620
621 BlockReference *block = new BlockReference(ref, compressed_size);
622
623 header->m_blocks.insert(block_source, (BlockTypeS *)block);
624 } else {
625 BlockReference *block = new BlockReference(ref, compressed_size);
626
627 header->m_blocks.push_front((BlockTypeS *)block);
628 }
629
630 // get rid of the compressed buffer
631
632 FreeImage_CloseMemory(hmem);
633
634 header->changed = TRUE;
635 header->page_count = -1;
636 }
637 }
638 }
639 }
640
641 void DLL_CALLCONV
642 FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
643 if (bitmap) {
644 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
645
646 if ((!header->read_only) && (header->locked_pages.empty())) {
647 if (FreeImage_GetPageCount(bitmap) > 1) {
648 BlockListIterator i = FreeImage_FindBlock(bitmap, page);
649
650 if (i != header->m_blocks.end()) {
651 switch((*i)->m_type) {
652 case BLOCK_CONTINUEUS :
653 header->m_blocks.erase(i);
654 break;
655
656 case BLOCK_REFERENCE :
657 header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference);
658 header->m_blocks.erase(i);
659 break;
660 }
661
662 header->changed = TRUE;
663 header->page_count = -1;
664 }
665 }
666 }
667 }
668 }
669
670
671 FIBITMAP * DLL_CALLCONV
672 FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
673 if (bitmap) {
674 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
675
676 // only lock if the page wasn't locked before...
677
678 for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
679 if (i->second == page) {
680 return NULL;
681 }
682 }
683
684 // open the bitmap
685
686 header->io->seek_proc(header->handle, 0, SEEK_SET);
687
688 void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
689
690 // load the bitmap data
691
692 if (data != NULL) {
693 FIBITMAP *dib = (header->node->m_plugin->load_proc != NULL) ? header->node->m_plugin->load_proc(header->io, header->handle, page, header->load_flags, data) : NULL;
694
695 // close the file
696
697 FreeImage_Close(header->node, header->io, header->handle, data);
698
699 // if there was still another bitmap open, get rid of it
700
701 if (dib) {
702 header->locked_pages[dib] = page;
703
704 return dib;
705 }
706
707 return NULL;
708 }
709 }
710
711 return NULL;
712 }
713
714 void DLL_CALLCONV
715 FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
716 if ((bitmap) && (page)) {
717 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
718
719 // find out if the page we try to unlock is actually locked...
720
721 if (header->locked_pages.find(page) != header->locked_pages.end()) {
722 // store the bitmap compressed in the cache for later writing
723
724 if (changed && !header->read_only) {
725 header->changed = TRUE;
726
727 // cut loose the block from the rest
728
729 BlockListIterator i = FreeImage_FindBlock(bitmap, header->locked_pages[page]);
730
731 // compress the data
732
733 DWORD compressed_size = 0;
734 BYTE *compressed_data = NULL;
735
736 // open a memory handle
737 FIMEMORY *hmem = FreeImage_OpenMemory();
738 // save the page to memory
739 FreeImage_SaveToMemory(header->cache_fif, page, hmem, 0);
740 // get the buffer from the memory stream
741 FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
742
743 // write the data to the cache
744
745 switch ((*i)->m_type) {
746 case BLOCK_CONTINUEUS :
747 {
748 int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
749
750 delete (*i);
751
752 *i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
753
754 break;
755 }
756
757 case BLOCK_REFERENCE :
758 {
759 BlockReference *reference = (BlockReference *)(*i);
760
761 header->m_cachefile->deleteFile(reference->m_reference);
762
763 delete (*i);
764
765 int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
766
767 *i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
768
769 break;
770 }
771 }
772
773 // get rid of the compressed data
774
775 FreeImage_CloseMemory(hmem);
776 }
777
778 // reset the locked page so that another page can be locked
779
780 FreeImage_Unload(page);
781
782 header->locked_pages.erase(page);
783 }
784 }
785 }
786
787 BOOL DLL_CALLCONV
788 FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) {
789 if (bitmap) {
790 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
791
792 if ((!header->read_only) && (header->locked_pages.empty())) {
793 if ((target != source) && ((target >= 0) && (target < FreeImage_GetPageCount(bitmap))) && ((source >= 0) && (source < FreeImage_GetPageCount(bitmap)))) {
794 BlockListIterator block_source = FreeImage_FindBlock(bitmap, target);
795 BlockListIterator block_target = FreeImage_FindBlock(bitmap, source);
796
797 header->m_blocks.insert(block_target, *block_source);
798 header->m_blocks.erase(block_source);
799
800 header->changed = TRUE;
801
802 return TRUE;
803 }
804 }
805 }
806
807 return FALSE;
808 }
809
810 BOOL DLL_CALLCONV
811 FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) {
812 if ((bitmap) && (count)) {
813 MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
814
815 if ((pages == NULL) || (*count == 0)) {
816 *count = (int)header->locked_pages.size();
817 } else {
818 int c = 0;
819
820 for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
821 pages[c] = i->second;
822
823 c++;
824
825 if (c == *count)
826 break;
827 }
828 }
829
830 return TRUE;
831 }
832
833 return FALSE;
834 }

  ViewVC Help
Powered by ViewVC 1.1.26