continuous pages
[fbpdf.git] / djvulibre.c
blob6c96badee686b7248c4018e7891d70660199e590
1 #include <stdlib.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <libdjvu/ddjvuapi.h>
5 #include "draw.h"
6 #include "doc.h"
8 #define MIN(a, b) ((a) < (b) ? (a) : (b))
10 struct doc {
11 ddjvu_context_t *ctx;
12 ddjvu_document_t *doc;
15 int djvu_handle(struct doc *doc)
17 ddjvu_message_t *msg;
18 msg = ddjvu_message_wait(doc->ctx);
19 while ((msg = ddjvu_message_peek(doc->ctx))) {
20 if (msg->m_any.tag == DDJVU_ERROR) {
21 fprintf(stderr,"ddjvu: %s\n", msg->m_error.message);
22 return 1;
24 ddjvu_message_pop(doc->ctx);
26 return 0;
29 static void djvu_render(ddjvu_page_t *page, int iw, int ih, void *bitmap)
31 ddjvu_format_t *fmt;
32 ddjvu_rect_t rect;
33 rect.x = 0;
34 rect.y = 0;
35 rect.w = iw;
36 rect.h = ih;
37 fmt = ddjvu_format_create(DDJVU_FORMAT_RGB24, 0, 0);
38 ddjvu_format_set_row_order(fmt, 1);
39 memset(bitmap, 0, ih * iw * 3);
40 ddjvu_page_render(page, DDJVU_RENDER_COLOR,
41 &rect, &rect, fmt, iw * 3, bitmap);
42 ddjvu_format_release(fmt);
45 int doc_draw(struct doc *doc, int p, int zoom, int rotate,
46 fbval_t *bitmap, int *rows, int *cols)
48 ddjvu_page_t *page;
49 ddjvu_pageinfo_t info;
50 int iw, ih, dpi;
51 unsigned char *bmp;
52 int i, j;
53 page = ddjvu_page_create_by_pageno(doc->doc, p - 1);
54 if (!page)
55 return -1;
56 while (!ddjvu_page_decoding_done(page))
57 if (djvu_handle(doc))
58 return -1;
59 if (rotate)
60 ddjvu_page_set_rotation(page, (4 - (rotate / 90 % 4)) & 3);
61 ddjvu_document_get_pageinfo(doc->doc, p - 1, &info);
62 dpi = ddjvu_page_get_resolution(page);
63 iw = ddjvu_page_get_width(page) * zoom * 10 / dpi;
64 ih = ddjvu_page_get_height(page) * zoom * 10 / dpi;
65 bmp = malloc(ih * iw * 3);
66 djvu_render(page, iw, ih, bmp);
67 ddjvu_page_release(page);
68 for (i = 0; i < MIN(*rows, ih); i++) {
69 unsigned char *src = bmp + i * iw * 3;
70 fbval_t *dst = bitmap + i * *cols + (*cols - MIN(*cols, iw)) / 2;
71 for (j = 0; j < MIN(iw, *cols); j++)
72 dst[j] = FB_VAL(src[j * 3], src[j * 3 + 1], src[j * 3 + 2]);
74 free(bmp);
75 *cols = MIN(*cols, iw);
76 *rows = MIN(*rows, ih);
77 return 0;
80 int doc_pages(struct doc *doc)
82 return ddjvu_document_get_pagenum(doc->doc);
85 struct doc *doc_open(char *path)
87 struct doc *doc = malloc(sizeof(*doc));
88 doc->ctx = ddjvu_context_create("fbpdf");
89 if (!doc->ctx)
90 goto fail;
91 doc->doc = ddjvu_document_create_by_filename(doc->ctx, path, 1);
92 if (!doc->doc)
93 goto fail;
94 while (!ddjvu_document_decoding_done(doc->doc))
95 if (djvu_handle(doc))
96 goto fail;
97 return doc;
98 fail:
99 doc_close(doc);
100 return NULL;
103 void doc_close(struct doc *doc)
105 if (doc->doc)
106 ddjvu_context_release(doc->ctx);
107 if (doc->ctx)
108 ddjvu_document_release(doc->doc);
109 free(doc);