1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 * Copyright (C) 2016 Mopria Alliance, Inc.
4 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <time.h>
20 #include "wprint_mupdf.h"
21 #include "lib_wprint.h"
22 #include "ipphelper.h"
23
24 #define TAG "wprint_mupdf"
25 #define MUPDF_DEFAULT_RESOLUTION 72
26 #define RGB_NUMBER_PIXELS_NUM_COMPONENTS 3
27
28 static pdf_render_ifc_t *pdf_render;
29
_mupdf_init(wprint_image_info_t * image_info)30 static void _mupdf_init(wprint_image_info_t *image_info) {
31 pdf_render = create_pdf_render_ifc();
32 }
33
34 /* Return current clock time in milliseconds */
get_millis()35 static long get_millis() {
36 struct timespec now;
37 clock_gettime(CLOCK_MONOTONIC, &now);
38 return (long) (((int64_t) now.tv_sec * 1000000000LL + now.tv_nsec) / 1000000);
39 }
40
_mupdf_get_hdr(wprint_image_info_t * image_info)41 static status_t _mupdf_get_hdr(wprint_image_info_t *image_info) {
42 double pageWidth, pageHeight;
43 float zoom;
44 unsigned int imageWidth;
45 unsigned int imageHeight;
46 int size;
47 char *rawBuffer;
48 status_t result;
49 int pages;
50
51 pages = pdf_render->openDocument(pdf_render, image_info->decoder_data.urlPath);
52 if (pages < 1) return ERROR;
53
54 result = pdf_render->getPageAttributes(pdf_render, image_info->decoder_data.page, &pageWidth,
55 &pageHeight);
56 if (result != OK) return result;
57
58 const float POINTS_PER_INCH = MUPDF_DEFAULT_RESOLUTION;
59 zoom = (image_info->pdf_render_resolution) / POINTS_PER_INCH;
60
61 imageWidth = (unsigned int) (pageWidth * zoom);
62 imageHeight = (unsigned int) (pageHeight * zoom);
63
64 image_info->width = imageWidth;
65 image_info->height = imageHeight;
66
67 size = imageWidth * imageHeight * 3;
68
69 rawBuffer = (char *) malloc((size_t) size);
70 if (!rawBuffer) return ERROR;
71
72 LOGI("Render page=%d w=%.0f h=%.0f res=%d zoom=%0.2f size=%d", image_info->decoder_data.page,
73 pageWidth, pageHeight, image_info->pdf_render_resolution, zoom, size);
74
75 long now = get_millis();
76
77 result = pdf_render->renderPageStripe(pdf_render, image_info->decoder_data.page, imageWidth,
78 imageHeight, zoom, rawBuffer);
79 if (result != OK) {
80 free(rawBuffer);
81 return result;
82 }
83
84 LOGI("Render complete in %ld ms", get_millis() - now);
85
86 image_info->decoder_data.pdf_info.fz_pixmap_ptr = rawBuffer;
87 image_info->decoder_data.pdf_info.bitmap_ptr = malloc(
88 image_info->width * RGB_NUMBER_PIXELS_NUM_COMPONENTS);
89 image_info->num_components = RGB_NUMBER_PIXELS_NUM_COMPONENTS;
90
91 return OK;
92 }
93
_mupdf_decode_row(wprint_image_info_t * image_info,int row)94 static unsigned char *_mupdf_decode_row(wprint_image_info_t *image_info, int row) {
95 unsigned char *rgbPixels = 0;
96
97 if (image_info->swath_start == -1) {
98 wprint_image_compute_rows_to_cache(image_info);
99 }
100
101 image_info->swath_start = row;
102 if (NULL != image_info->decoder_data.pdf_info.fz_pixmap_ptr) {
103 rgbPixels = (unsigned char *) image_info->decoder_data.pdf_info.bitmap_ptr;
104 memcpy(rgbPixels, (char *) (image_info->decoder_data.pdf_info.fz_pixmap_ptr) +
105 row * image_info->width * RGB_NUMBER_PIXELS_NUM_COMPONENTS,
106 image_info->width * RGB_NUMBER_PIXELS_NUM_COMPONENTS);
107 }
108 return rgbPixels;
109 }
110
_mupdf_cleanup(wprint_image_info_t * image_info)111 static status_t _mupdf_cleanup(wprint_image_info_t *image_info) {
112 LOGD("MUPDF: _mupdf_cleanup(): Enter");
113 if (NULL != image_info->decoder_data.pdf_info.fz_pixmap_ptr) {
114 free(image_info->decoder_data.pdf_info.fz_pixmap_ptr);
115 image_info->decoder_data.pdf_info.fz_pixmap_ptr = NULL;
116 }
117 if (image_info->decoder_data.pdf_info.bitmap_ptr != NULL) {
118 free(image_info->decoder_data.pdf_info.bitmap_ptr);
119 }
120 pdf_render->destroy(pdf_render);
121 pdf_render = NULL;
122 return OK;
123 }
124
_mupdf_supports_subsampling(wprint_image_info_t * image_info)125 static status_t _mupdf_supports_subsampling(wprint_image_info_t *image_info) {
126 LOGI("MUPDF: _mupdf_supports_subsampling(): Enter");
127 return ERROR;
128 }
129
_mupdf_native_units(wprint_image_info_t * image_info)130 static int _mupdf_native_units(wprint_image_info_t *image_info) {
131 return image_info->pdf_render_resolution;
132 }
133
134 static const image_decode_ifc_t _mupdf_decode_ifc = {&_mupdf_init, &_mupdf_get_hdr,
135 &_mupdf_decode_row, &_mupdf_cleanup,
136 &_mupdf_supports_subsampling,
137 &_mupdf_native_units,};
138
139 const image_decode_ifc_t *wprint_mupdf_decode_ifc = &_mupdf_decode_ifc;