fbpdf.1: update and improve the manual page
[fbpdf.git] / djvulibre.c
blobad0cccea1cd1affca73e30964e4110d55cdcc7cd
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 void *doc_draw(struct doc *doc, int p, int zoom, int rotate, int *rows, int *cols)
47 ddjvu_page_t *page;
48 ddjvu_pageinfo_t info;
49 int iw, ih, dpi;
50 unsigned char *bmp;
51 fbval_t *pbuf;
52 int i, j;
53 page = ddjvu_page_create_by_pageno(doc->doc, p - 1);
54 if (!page)
55 return NULL;
56 while (!ddjvu_page_decoding_done(page))
57 if (djvu_handle(doc))
58 return NULL;
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 / dpi;
64 ih = ddjvu_page_get_height(page) * zoom / dpi;
65 if (!(bmp = malloc(ih * iw * 3))) {
66 ddjvu_page_release(page);
67 return NULL;
69 djvu_render(page, iw, ih, bmp);
70 ddjvu_page_release(page);
71 if (!(pbuf = malloc(ih * iw * sizeof(pbuf[0])))) {
72 free(bmp);
73 return NULL;
75 for (i = 0; i < ih; i++) {
76 unsigned char *src = bmp + i * iw * 3;
77 fbval_t *dst = pbuf + i * iw;
78 for (j = 0; j < iw; j++)
79 dst[j] = FB_VAL(src[j * 3], src[j * 3 + 1], src[j * 3 + 2]);
81 free(bmp);
82 *cols = iw;
83 *rows = ih;
84 return pbuf;
87 int doc_pages(struct doc *doc)
89 return ddjvu_document_get_pagenum(doc->doc);
92 struct doc *doc_open(char *path)
94 struct doc *doc = malloc(sizeof(*doc));
95 doc->ctx = ddjvu_context_create("fbpdf");
96 if (!doc->ctx)
97 goto fail;
98 doc->doc = ddjvu_document_create_by_filename(doc->ctx, path, 1);
99 if (!doc->doc)
100 goto fail;
101 while (!ddjvu_document_decoding_done(doc->doc))
102 if (djvu_handle(doc))
103 goto fail;
104 return doc;
105 fail:
106 doc_close(doc);
107 return NULL;
110 void doc_close(struct doc *doc)
112 if (doc->doc)
113 ddjvu_context_release(doc->ctx);
114 if (doc->ctx)
115 ddjvu_document_release(doc->doc);
116 free(doc);