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 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 */ 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 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 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 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 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 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;