root/ImageMagick/trunk/coders/djvu.c

Revision 1, 31.3 KB (checked in by cristy, 3 months ago)


Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                         DDDD       J  V   V  U   U                          %
7%                         D   D      J  V   V  U   U                          %
8%                         D   D      J  V   V  U   U                          %
9%                         D   D  J   J   V V   U   U                          %
10%                         DDDD    JJJ     V     UUU                           %
11%                                                                             %
12%                                                                             %
13%                             Read DjVu Images.                               %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                 July 1992                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
21%  dedicated to making software imaging solutions freely available.           %
22%                                                                             %
23%  You may not use this file except in compliance with the License.  You may  %
24%  obtain a copy of the License at                                            %
25%                                                                             %
26%    http://www.imagemagick.org/script/license.php                            %
27%                                                                             %
28%  Unless required by applicable law or agreed to in writing, software        %
29%  distributed under the License is distributed on an "AS IS" BASIS,          %
30%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31%  See the License for the specific language governing permissions and        %
32%  limitations under the License.                                             %
33%                                                                             %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40  Include declarations.
41*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/cache.h"
46#include "magick/constitute.h"
47#include "magick/exception.h"
48#include "magick/exception-private.h"
49#include "magick/list.h"
50#include "magick/magick.h"
51#include "magick/memory_.h"
52#include "magick/monitor.h"
53#include "magick/monitor-private.h"
54#include "magick/quantum-private.h"
55#include "magick/static.h"
56#include "magick/string_.h"
57#include "magick/module.h"
58#if defined(MAGICKCORE_DJVU_DELEGATE)
59#include <libdjvu/ddjvuapi.h>
60#endif
61
62/*
63%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64%                                                                             %
65%                                                                             %
66%                                                                             %
67%   I s D J V U                                                               %
68%                                                                             %
69%                                                                             %
70%                                                                             %
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72%
73%  IsDJVU() returns MagickTrue if the image format type, identified by the
74%  magick string, is DJVU.
75%
76%  The format of the IsDJVU method is:
77%
78%      MagickBooleanType IsDJVU(const unsigned char *magick,const size_t length)
79%
80%  A description of each parameter follows:
81%
82%    o magick: compare image format pattern against these bytes.
83%
84%    o length: Specifies the length of the magick string.
85%
86*/
87static MagickBooleanType IsDJVU(const unsigned char *magick,const size_t length)
88{
89  if (length < 8)
90    return(MagickFalse);
91  if (memcmp(magick,"AT&TFORM",8) == 0)
92    return(MagickTrue);
93  return(MagickFalse);
94}
95
96#if defined(MAGICKCORE_DJVU_DELEGATE)
97/*
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99%                                                                             %
100%                                                                             %
101%                                                                             %
102%   R e a d D J V U I m a g e                                                 %
103%                                                                             %
104%                                                                             %
105%                                                                             %
106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107%
108%  ReadDJVUImage() reads DJVU image and returns it.  It allocates the memory
109%  necessary for the new Image structure and returns a pointer to the new
110%  image or set of images.
111%
112%  The format of the ReadDJVUImage method is:
113%
114%      Image *ReadDJVUImage(const ImageInfo *image_info,
115%        ExceptionInfo *exception)
116%
117%  A description of each parameter follows:
118%
119%    o image_info: the image info.
120%
121%    o exception: return any errors or warnings in this structure.
122%
123*/
124
125#if defined(__cplusplus) || defined(c_plusplus)
126extern "C" {
127#endif
128
129typedef struct _LoadContext
130   LoadContext;
131
132struct _LoadContext
133{
134  ddjvu_context_t* context;
135  ddjvu_document_t *document;
136  ddjvu_page_t *page;
137  int streamid;
138  int pages;
139  Image *image;
140};
141
142#define BLOCKSIZE  65536
143#if 0
144static void
145pump_data(Image *image, LoadContext* lc)
146{
147        int blocksize = BLOCKSIZE;
148        char data[BLOCKSIZE];
149        int size;
150
151        /* i might check for a condition! */
152        while ((size = (size_t) ReadBlob(image,(size_t) blocksize,data)) == blocksize) {
153                ddjvu_stream_write(lc->document, lc->streamid, data, size);
154        }
155        if (size)
156                ddjvu_stream_write(lc->document, lc->streamid, data, size);
157        ddjvu_stream_close(lc->document, lc->streamid, 0);
158}
159#endif
160
161/* returns NULL only after all is delivered! */
162static ddjvu_message_t*
163pump_data_until_message(LoadContext *lc,Image *image) /* ddjvu_context_t *context, type ddjvu_document_type_t */
164{
165        unsigned long blocksize = BLOCKSIZE;
166        unsigned char data[BLOCKSIZE];
167        unsigned long size;
168        ddjvu_message_t *message;
169
170        /* i might check for a condition! */
171        while (!(message = ddjvu_message_peek(lc->context))
172               && (size = (unsigned long) ReadBlob(image,(size_t) blocksize,data)) == blocksize) {
173                ddjvu_stream_write(lc->document, lc->streamid, (char *) data, size);
174        }
175        if (message)
176                return message;
177        if (size)
178                ddjvu_stream_write(lc->document, lc->streamid, (char *) data, size);
179        ddjvu_stream_close(lc->document, lc->streamid, 0);
180        return NULL;
181}
182#define DEBUG 0
183
184#if DEBUG
185static const char*
186message_tag_name(ddjvu_message_tag_t tag)
187{
188   static char* names[] =
189      {
190         "ERROR",
191         "INFO",
192         "NEWSTREAM",
193         "DOCINFO",
194         "PAGEINFO",
195         "RELAYOUT",
196         "REDISPLAY",
197         "CHUNK",
198         "THUMBNAIL",
199         "PROGRESS",
200      };
201   if (tag <= DDJVU_PROGRESS)
202      return names[tag];
203   else {
204      /* bark! */
205      return 0;
206   }
207}
208#endif
209
210/* write out nice info on the message,
211 * and store in *user* data the info on progress.
212 * */
213int
214process_message(ddjvu_message_t *message)
215{
216
217#if 0
218   ddjvu_context_t* context= message->m_any.context;
219#endif
220
221   if (! message)
222      return(-1);
223#if DEBUG
224   printf("*** %s: %s.\n",__FUNCTION__, message_tag_name(message->m_any.tag));
225#endif
226
227
228   switch (message->m_any.tag){
229   case DDJVU_DOCINFO:
230   {
231      ddjvu_document_t* document= message->m_any.document;
232      /* ddjvu_document_decoding_status  is set by libdjvu! */
233      /* we have some info on the document  */
234      LoadContext *lc = (LoadContext *) ddjvu_document_get_user_data(document);
235      lc->pages = ddjvu_document_get_pagenum(document);
236#if DEBUG
237      printf("the doc has %d pages\n", ddjvu_document_get_pagenum(document));
238#endif
239      break;
240   }
241   case DDJVU_CHUNK:
242#if DEBUG
243           printf("the name of the chunk is: %s\n", message->m_chunk.chunkid);
244#endif
245           break;
246
247
248   case DDJVU_RELAYOUT:
249   case DDJVU_PAGEINFO:
250   {
251#if 0
252      ddjvu_page_t* page = message->m_any.page;
253      page_info* info = ddjvu_page_get_user_data(page);
254
255      printf("page decoding status: %d %s%s%s\n",
256             ddjvu_page_decoding_status(page),
257             status_color, status_name(ddjvu_page_decoding_status(page)), color_reset);
258
259      printf("the page LAYOUT changed: width x height: %d x %d @ %d dpi. Version %d, type %d\n",
260             // printf("page info:\n width x height: %d x %d @ %d dpi, version %d, type %d\n",
261             ddjvu_page_get_width(page),
262             ddjvu_page_get_height(page),
263             ddjvu_page_get_resolution(page),
264             ddjvu_page_get_version(page),
265             /* DDJVU_PAGETYPE_BITONAL */
266             ddjvu_page_get_type(page));
267
268      info->info = 1;
269#endif
270      break;
271   }
272
273   case DDJVU_REDISPLAY:
274   {
275
276#if 0
277    ddjvu_page_t* page = message->m_any.page;
278      page_info* info = ddjvu_page_get_user_data(page);
279
280      printf("the page can/should be REDISPLAYED\n");
281      info->display = 1;
282#endif
283      break;
284   }
285
286   case DDJVU_PROGRESS:
287#if DEBUG
288           printf("PROGRESS:\n");
289#endif
290           break;
291   case DDJVU_ERROR:
292           printf("simply ERROR!\n message:\t%s\nfunction:\t%s(file %s)\nlineno:\t%d\n",
293                  message->m_error.message,
294                  message->m_error.function,
295                  message->m_error.filename,
296                  message->m_error.lineno);
297           break;
298   case DDJVU_INFO:
299#if DEBUG
300           printf("INFO: %s!\n", message->m_info.message);
301#endif
302           break;
303   default:
304      printf("unexpected\n");
305   };
306  return(message->m_any.tag);
307}
308
309
310#if defined(__cplusplus) || defined(c_plusplus)
311}
312#endif
313
314
315#define RGB 1
316
317/*
318 * DjVu advertised readiness to provide bitmap: So get it!
319 * we use the RGB format!
320 */
321static void
322get_page_image(LoadContext *lc, ddjvu_page_t *page, int x, int y, int w, int h, QuantumInfo* quantum_info)
323{
324  ddjvu_format_t
325    *format;
326
327  ddjvu_page_type_t
328    type;
329
330  Image
331    *image;
332
333  int
334    ret,
335    stride;
336
337  unsigned char
338    *q;
339
340        ddjvu_rect_t rect;
341        rect.x = x;
342        rect.y = y;
343        rect.w = (unsigned int) w;             /* /10 */
344        rect.h = (unsigned int) h;             /* /10 */
345
346        image = lc->image;
347        type = ddjvu_page_get_type(lc->page);
348
349        /* stride of this temporary buffer: */
350        stride = (type == DDJVU_PAGETYPE_BITONAL)?
351                (lc->image->columns + 7)/8:
352                lc->image->columns *3;
353
354        q = (unsigned char *) AcquireQuantumMemory(lc->image->rows,stride);
355
356
357        format = ddjvu_format_create(
358                (type == DDJVU_PAGETYPE_BITONAL)?DDJVU_FORMAT_LSBTOMSB : DDJVU_FORMAT_RGB24,
359                /* DDJVU_FORMAT_RGB24
360                 * DDJVU_FORMAT_RGBMASK32*/
361                /* DDJVU_FORMAT_RGBMASK32 */
362                0, NULL);
363
364#if 0
365        /* fixme:  ThrowReaderException is a macro, which uses  `exception' variable */
366        if (format == NULL)
367                {
368                        abort();
369                        /* ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); */
370                }
371
372#endif
373        ddjvu_format_set_row_order(format, 1);
374        ddjvu_format_set_y_direction(format, 1);
375
376        ret = ddjvu_page_render(page,
377                                    DDJVU_RENDER_COLOR, /* ddjvu_render_mode_t */
378                                    &rect,
379                                    &rect,     /* mmc: ?? */
380                                    format,
381                                    stride, /* ?? */
382                                    (char*)q);
383        ddjvu_format_release(format);
384
385
386        if (type == DDJVU_PAGETYPE_BITONAL) {
387                /*  */
388#if DEBUG
389                printf("%s: expanding BITONAL page/image\n", __FUNCTION__);
390#endif
391                register IndexPacket *indexes;
392                unsigned long bit, byte;
393
394                for (y=0; y < (long) image->rows; y++)
395                        {
396                                PixelPacket * o = QueueAuthenticPixels(image,0,y,image->columns,1,&image->exception);
397                                if (o == (PixelPacket *) NULL)
398                                        break;
399                                indexes=GetAuthenticIndexQueue(image);
400                                bit=0;
401                                byte=0;
402
403                                /* fixme:  the non-aligned, last =<7 bits ! that's ok!!!*/
404                                for (x= 0; x < (long) image->columns; x++)
405                                        {
406                                                if (bit == 0) byte= (unsigned long) q[(y * stride) + (x / 8)];
407
408                                                indexes[x]=(IndexPacket) (((byte & 0x01) != 0) ? 0x00 : 0x01);
409                                                bit++;
410                                                if (bit == 8)
411                                                        bit=0;
412                                                byte>>=1;
413                                        }
414                                if (SyncAuthenticPixels(image,&image->exception) == MagickFalse)
415                                        break;
416                        }
417                SyncImage(image);
418        } else {
419#if DEBUG
420                printf("%s: expanding PHOTO page/image\n", __FUNCTION__);
421#endif
422                /* now transfer line-wise: */
423                long i;
424#if 0
425                /* old: */
426                char* r;
427#else
428                register PixelPacket *r;
429#endif
430
431                for (i = 0;i< (long) lc->image->rows; i++)
432                        {
433#if DEBUG
434                               if (i % 1000 == 0) printf("%d\n",i);
435#endif
436                               r = QueueAuthenticPixels(lc->image,0,i,lc->image->columns,1,&image->exception);
437
438                                ImportQuantumPixels(lc->image,
439                                                    (CacheView *) NULL,
440                                                    quantum_info,
441                                                    RGBQuantum, /*GrayQuantum*/
442                                                    q+i*stride,&image->exception);
443                                SyncAuthenticPixels(lc->image,&image->exception);
444                        }
445        }
446        q=(unsigned char *) RelinquishMagickMemory(q);
447}
448
449
450#if defined(MAGICKCORE_DJVU_DELEGATE)
451
452static int
453get_page_line(LoadContext *lc, int row, QuantumInfo* quantum_info)
454{
455  ddjvu_format_t
456    *format;
457
458  int
459    ret;
460
461  size_t
462    stride;
463
464  unsigned char
465    *q;
466
467        ddjvu_rect_t rect, pagerect;
468        rect.x = 0;
469        rect.y = row;
470        rect.w = lc->image->columns;             /* /10 */
471        rect.h = 1;             /* /10 */
472
473        pagerect.x = 0;
474        pagerect.y = 0;
475        pagerect.w = lc->image->columns;
476        pagerect.h = lc->image->rows;
477
478
479        format = ddjvu_format_create(
480#if RGB
481                DDJVU_FORMAT_RGB24
482#else
483                DDJVU_FORMAT_GREY8
484#endif
485                ,
486                0, NULL);
487        ddjvu_format_set_row_order(format, 1);
488        ddjvu_format_set_y_direction(format, 1);
489
490        stride=1;
491#if RGB
492        stride=3;
493#endif
494        q = (unsigned char *) AcquireQuantumMemory(lc->image->columns,stride);
495
496        ret = ddjvu_page_render(lc->page,
497                                    DDJVU_RENDER_COLOR, /* ddjvu_render_mode_t */
498                                    &pagerect,
499                                    &rect,     /* mmc: ?? */
500                                    format,
501                                    pagerect.w * 3, /* ?? */
502                                    (char*)q);
503
504        ImportQuantumPixels(lc->image,
505                            (CacheView *) NULL,
506                            quantum_info,
507#if RGB
508                            RGBQuantum
509#else
510                            GrayQuantum
511#endif
512                            ,q,&lc->image->exception);
513        q=(unsigned char *) RelinquishMagickMemory(q);
514        ddjvu_format_release(format);
515        return ret;
516}
517#endif
518
519/*
520%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
521%                                                                             %
522%                                                                             %
523%                                                                             %
524%   R e a d O n e D J V U I m a g e                                           %
525%                                                                             %
526%                                                                             %
527%                                                                             %
528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
529%
530%  ReadOneDJVUImage() reads a Portable Network Graphics (DJVU) image file
531%  (minus the 8-byte signature)  and returns it.  It allocates the memory
532%  necessary for the new Image structure and returns a pointer to the new
533%  image.
534%
535%  The format of the ReadOneDJVUImage method is:
536%
537%      Image *ReadOneDJVUImage(MngInfo *mng_info, const ImageInfo *image_info,
538%         ExceptionInfo *exception)
539%
540%  A description of each parameter follows:
541%
542%    o mng_info: Specifies a pointer to a MngInfo structure.
543%
544%    o image_info: the image info.
545%
546%    o exception: return any errors or warnings in this structure.
547%
548*/
549
550static inline double MagickMax(const double x,const double y)
551{
552  if (x > y)
553    return(x);
554  return(y);
555}
556
557static Image *ReadOneDJVUImage(LoadContext* lc,const int pagenum,
558  const ImageInfo *image_info,ExceptionInfo *exception)
559{
560  ddjvu_page_type_t
561     type;
562
563  ddjvu_pageinfo_t info;
564  QuantumInfo *quantum_info;
565  ddjvu_message_t *message;
566  Image *image;
567  int logging;
568  int tag;
569
570        /* so, we know that the page is there! Get its dimension, and  */
571
572        /* Read one DJVU image */
573        image = lc->image;
574
575        /* register PixelPacket *q; */
576
577        logging=LogMagickEvent(CoderEvent,GetMagickModule(), "  enter ReadOneDJVUImage()");
578
579#if DEBUG
580        printf("====  Loading the page %d\n", pagenum);
581#endif
582        lc->page = ddjvu_page_create_by_pageno(lc->document, pagenum); /*  0? */
583
584        /* pump data untill the page is ready for rendering. */
585        tag=(-1);
586        do {
587                while ((message = ddjvu_message_peek(lc->context)))
588                        {
589                                tag=process_message(message);
590                                if (tag == 0) break;
591                                ddjvu_message_pop(lc->context);
592                        }
593                /* fixme: maybe exit? */
594                /* if (lc->error) break; */
595
596                message = pump_data_until_message(lc,image);
597                if (message)
598                        do {
599                                tag=process_message(message);
600                                if (tag == 0) break;
601                                ddjvu_message_pop(lc->context);
602                        } while ((message = ddjvu_message_peek(lc->context)));
603        } while (!ddjvu_page_decoding_done(lc->page));
604
605        ddjvu_document_get_pageinfo(lc->document, pagenum, &info);
606
607        image->x_resolution = (float) info.dpi;
608        image->y_resolution =(float) info.dpi;
609        if (image_info->density != (char *) NULL)
610          {
611            int
612              flags;
613
614            GeometryInfo
615              geometry_info;
616
617            /*
618              Set rendering resolution.
619            */
620            flags=ParseGeometry(image_info->density,&geometry_info);
621            image->x_resolution=geometry_info.rho;
622            image->y_resolution=geometry_info.sigma;
623            if ((flags & SigmaValue) == 0)
624              image->y_resolution=image->x_resolution;
625            info.width*=image->x_resolution/info.dpi;
626            info.height*=image->y_resolution/info.dpi;
627            info.dpi=(long) MagickMax(image->x_resolution,image->y_resolution);
628          }
629        type = ddjvu_page_get_type(lc->page);
630
631        /* double -> float! */
632        /* image->gamma = (float)ddjvu_page_get_gamma(lc->page); */
633
634        /* mmc:  set  image->depth  */
635        /* mmc:  This from the type */
636
637        image->columns=(unsigned long) info.width;
638        image->rows=(unsigned long) info.height;
639
640        /* mmc: bitonal should be palettized, and compressed! */
641        if (type == DDJVU_PAGETYPE_BITONAL){
642                image->colorspace = GRAYColorspace;
643                image->storage_class = PseudoClass;
644                image->depth =  8UL;    /* i only support that? */
645                image->colors= 2;
646                if (AcquireImageColormap(image,image->colors) == MagickFalse)
647                  ThrowReaderException(ResourceLimitError,
648                   "MemoryAllocationFailed");
649        } else {
650                image->colorspace = RGBColorspace;
651                image->storage_class = DirectClass;
652                /* fixme:  MAGICKCORE_QUANTUM_DEPTH ?*/
653                image->depth =  8UL;    /* i only support that? */
654
655                image->matte = MagickTrue;
656                /* is this useful? */
657        }
658#if DEBUG
659        printf("now filling %ld x %ld\n", image->columns,image->rows);
660#endif
661
662
663#if 1                           /* per_line */
664        quantum_info=AcquireQuantumInfo(image_info,image);
665        if (quantum_info == (QuantumInfo *) NULL)
666          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
667
668        /* q = QueueAuthenticPixels(image,0,0,image->columns,image->rows); */
669        get_page_image(lc, lc->page, 0, 0, info.width, info.height, quantum_info);
670#else
671        int i;
672        for (i = 0;i< image->rows; i++)
673                {
674                        printf("%d\n",i);
675                        q = QueueAuthenticPixels(image,0,i,image->columns,1);
676                        get_page_line(lc, i, quantum_info);
677                        SyncAuthenticPixels(image);
678                }
679
680#endif /* per_line */
681
682
683#if DEBUG
684        printf("END: finished filling %ld x %ld\n", image->columns,image->rows);
685#endif
686
687        SyncImage(image);
688        quantum_info=DestroyQuantumInfo(quantum_info);
689        /* indexes=GetAuthenticIndexQueue(image); */
690        /* mmc: ??? Convert PNM pixels to runlength-encoded MIFF packets. */
691        /* image->colors =  */
692
693        /* how is the line padding  / stride? */
694
695        if (lc->page) {
696                ddjvu_page_release(lc->page);
697                lc->page = NULL;
698        }
699
700        /* image->page.y=mng_info->y_off[mng_info->object_id]; */
701        if (tag == 0)
702          image=DestroyImage(image);
703        return image;
704        /* end of reading one DJVU page/image */
705}
706
707#if 0
708/* palette */
709  if (AcquireImageColormap(image,2) == MagickFalse)
710    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
711  /*
712    Monochrome colormap.   mmc: this the default!
713  */
714  image->colormap[0].red=QuantumRange;
715  image->colormap[0].green=QuantumRange;
716  image->colormap[0].blue=QuantumRange;
717  image->colormap[1].red=0;
718  image->colormap[1].green=0;
719  image->colormap[1].blue=0;
720#endif
721
722static void djvu_close_lc(LoadContext* lc)
723{
724        if (lc->document)
725                ddjvu_document_release(lc->document);
726        if (lc->context)
727                ddjvu_context_release(lc->context);
728        if (lc->page)
729                ddjvu_page_release(lc->page);
730        RelinquishMagickMemory(lc);
731}
732
733static Image *ReadDJVUImage(const ImageInfo *image_info,
734  ExceptionInfo *exception)
735{
736  const char
737    *url;
738
739  ddjvu_message_t
740    *message;
741
742  Image
743    *image,
744    *images;
745
746  int
747    logging,
748    use_cache;
749
750  LoadContext
751    *lc;
752
753  MagickBooleanType
754    status;
755
756  register long
757    i;
758
759  /*
760   * Open image file.
761   */
762  assert(image_info != (const ImageInfo *) NULL);
763  assert(image_info->signature == MagickSignature);
764
765
766  if (image_info->debug != MagickFalse)
767    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename);
768
769  assert(exception != (ExceptionInfo *) NULL);
770  assert(exception->signature == MagickSignature);
771
772
773  logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadDJVUImage()");
774
775  image = AcquireImage(image_info); /* mmc: ?? */
776
777
778  lc = (LoadContext *) NULL;
779  status = OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
780  if (status == MagickFalse)
781    ThrowReaderException(FileOpenError,"UnableToOpenFile");
782  /*
783    Verify DJVU signature.
784  */
785#if 0
786  count = ReadBlob(image,8,(unsigned char *) magic_number);
787
788  /* IsDJVU(const unsigned char *magick,const size_t length) */
789  if (memcmp(magic_number,"AT&TFORM",8) != 0)
790    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
791#endif
792
793
794  /*
795   * Allocate a LoadContext structure.
796   */
797  lc = (LoadContext *) AcquireMagickMemory(sizeof(*lc));
798  if (lc == NULL)
799    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
800
801
802  /*
803   * Initialize members of the MngInfo structure.
804   */
805  (void) ResetMagickMemory(lc,0,sizeof(LoadContext));
806
807  lc->image = image;
808  lc->pages = 0;
809  lc->context = ddjvu_context_create("ImageMagick djvu loader"); /* g_program_name */
810
811  ddjvu_cache_set_size(lc->context, 1); /* right? */
812  use_cache = 0;
813  /* document: here we don't have a filename, but, for the sake of generality, a FILE* ! */
814  url="http://maruska.dyndns.org/fake.djvu";
815  lc->document = ddjvu_document_create(lc->context, url, use_cache); /* don't cache */
816  ddjvu_document_set_user_data(lc->document, lc);
817
818
819  /* now we wait the message-request for data: */
820  message = ddjvu_message_wait(lc->context);
821
822  if (message->m_any.tag != DDJVU_NEWSTREAM) {
823          /* fixme: the djvu context, document! */
824
825          ddjvu_document_release(lc->document);
826          ddjvu_context_release(lc->context);
827
828          RelinquishMagickMemory(lc);
829
830          ThrowReaderException(ResourceLimitError,"Djvu initial message: unexpected type");
831          return NULL;    /* error! */
832  };
833
834  lc->streamid = message->m_newstream.streamid;
835  ddjvu_message_pop(lc->context);
836
837  message = pump_data_until_message(lc,image);
838  /* now process the messages: */
839
840
841  if (message) do {
842          process_message(message);
843          ddjvu_message_pop(lc->context);
844  } while ((message = ddjvu_message_peek(lc->context)));
845
846  /* fixme: i hope we have not read any messages pertinent(?) related to the page itself!  */
847
848  while (lc->pages == 0) {
849          message = ddjvu_message_wait(lc->context);
850          process_message(message);
851          ddjvu_message_pop(lc->context);
852  }
853
854  images=NewImageList();
855  i=0;
856  if (image_info->number_scenes != 0)
857    i=image_info->scene;
858  for ( ; i < (long) lc->pages; i++)
859  {
860    image=ReadOneDJVUImage(lc,i,image_info,exception);
861    if (image == (Image *) NULL)
862      break;
863    AppendImageToList(&images,CloneImageList(image,exception));
864    if (image_info->number_scenes != 0)
865      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
866        break;
867  }
868  djvu_close_lc(lc);
869  (void) CloseBlob(images);
870  if (image != (Image *) NULL)
871    image=DestroyImageList(image);
872
873#if 0
874  if ((image->page.width == 0) && (image->page.height == 0))
875    {
876      image->page.width = image->columns+image->page.x;
877      image->page.height = image->rows+image->page.y;
878    }
879  if (image->columns == 0 || image->rows == 0)
880    {
881      if (logging != MagickFalse)
882        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
883          "exit ReadDJVUImage() with error.");
884      ThrowReaderException(CorruptImageError,"CorruptImage");
885    }
886
887  if (logging != MagickFalse)
888    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadDJVUImage()");
889#endif
890
891
892  return(GetFirstImageInList(images));
893}
894#endif
895
896/*
897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898%                                                                             %
899%                                                                             %
900%                                                                             %
901%   R e g i s t e r D J V U I m a g e                                         %
902%                                                                             %
903%                                                                             %
904%                                                                             %
905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
906%
907%  RegisterDJVUImage() adds attributes for the DJVU image format to
908%  the list of supported formats.  The attributes include the image format
909%  tag, a method to read and/or write the format, whether the format
910%  supports the saving of more than one frame to the same file or blob,
911%  whether the format supports native in-memory I/O, and a brief
912%  description of the format.
913%
914%  The format of the RegisterDJVUImage method is:
915%
916%      unsigned long RegisterDJVUImage(void)
917%
918*/
919ModuleExport unsigned long RegisterDJVUImage(void)
920{
921  char
922    version[MaxTextExtent];
923
924  MagickInfo
925    *entry;
926
927  static const char
928    *DJVUNote =
929    {
930      "See http://www.djvuzone.org/ for details about the DJVU format.  The\n"
931      "DJVU 1.2 specification is available there and at\n"
932      "ftp://swrinde.nde.swri.edu/pub/djvu/documents/."
933    };
934
935  *version='\0';
936#if defined(DJVU_LIBDJVU_VER_STRING)
937  (void) ConcatenateMagickString(version,"libdjvu ",MaxTextExtent);
938  (void) ConcatenateMagickString(version,DJVU_LIBDJVU_VER_STRING,MaxTextExtent);
939#endif
940  entry=SetMagickInfo("DJVU");
941#if defined(MAGICKCORE_DJVU_DELEGATE)
942  entry->decoder=(DecodeImageHandler *) ReadDJVUImage;
943#endif
944  entry->raw=MagickTrue;
945  entry->magick=(IsImageFormatHandler *) IsDJVU;
946  entry->adjoin=MagickFalse;
947  entry->thread_support=MagickTrue;
948  entry->description=AcquireString("Déjà vu");
949  entry->module=AcquireString("DJVU");
950  if (*version != '\0')
951    entry->version=AcquireString(version);
952  entry->note=AcquireString(DJVUNote);
953  (void) RegisterMagickInfo(entry);
954  return(MagickImageCoderSignature);
955}
956
957/*
958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959%                                                                             %
960%                                                                             %
961%                                                                             %
962%   U n r e g i s t e r D J V U I m a g e                                     %
963%                                                                             %
964%                                                                             %
965%                                                                             %
966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967%
968%  UnregisterDJVUImage() removes format registrations made by the
969%  DJVU module from the list of supported formats.
970%
971%  The format of the UnregisterDJVUImage method is:
972%
973%      UnregisterDJVUImage(void)
974%
975*/
976ModuleExport void UnregisterDJVUImage(void)
977{
978  (void) UnregisterMagickInfo("DJVU");
979}
Note: See TracBrowser for help on using the browser.