Home | History | Annotate | Download | only in plugins
      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;