lib_pclm.c revision 2e2be0f9ea6839e000a98ba83daa57c8c3258b6c
13bf66744d61d18c66d46f2608de0467ad3df0268Mopria/*
23bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 The Android Open Source Project
33bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 Mopria Alliance, Inc.
43bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
53bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
63bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Licensed under the Apache License, Version 2.0 (the "License");
73bf66744d61d18c66d46f2608de0467ad3df0268Mopria * you may not use this file except in compliance with the License.
83bf66744d61d18c66d46f2608de0467ad3df0268Mopria * You may obtain a copy of the License at
93bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
103bf66744d61d18c66d46f2608de0467ad3df0268Mopria *      http://www.apache.org/licenses/LICENSE-2.0
113bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
123bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Unless required by applicable law or agreed to in writing, software
133bf66744d61d18c66d46f2608de0467ad3df0268Mopria * distributed under the License is distributed on an "AS IS" BASIS,
143bf66744d61d18c66d46f2608de0467ad3df0268Mopria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
153bf66744d61d18c66d46f2608de0467ad3df0268Mopria * See the License for the specific language governing permissions and
163bf66744d61d18c66d46f2608de0467ad3df0268Mopria * limitations under the License.
173bf66744d61d18c66d46f2608de0467ad3df0268Mopria */
183bf66744d61d18c66d46f2608de0467ad3df0268Mopria
193bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include <sys/types.h>
203bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include <stdio.h>
213bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include <stdlib.h>
223bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include <math.h>
233bf66744d61d18c66d46f2608de0467ad3df0268Mopria
243bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include "lib_pcl.h"
253bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include "wprint_image.h"
263bf66744d61d18c66d46f2608de0467ad3df0268Mopria
273bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include "pclm_wrapper_api.h"
283bf66744d61d18c66d46f2608de0467ad3df0268Mopria
293bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include "media.h"
303bf66744d61d18c66d46f2608de0467ad3df0268Mopria#include "wprint_debug.h"
313bf66744d61d18c66d46f2608de0467ad3df0268Mopria
323bf66744d61d18c66d46f2608de0467ad3df0268Mopria#define TAG "lib_pclm"
333bf66744d61d18c66d46f2608de0467ad3df0268Mopria
343bf66744d61d18c66d46f2608de0467ad3df0268Mopria/*
353bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Store a valid media_size name into media_name
363bf66744d61d18c66d46f2608de0467ad3df0268Mopria */
373bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic void _get_pclm_media_size_name(pcl_job_info_t *job_info, media_size_t media_size,
383bf66744d61d18c66d46f2608de0467ad3df0268Mopria        char *media_name) {
393bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int i = 0;
403bf66744d61d18c66d46f2608de0467ad3df0268Mopria    for (i = 0; i < SUPPORTED_MEDIA_SIZE_COUNT; i++) {
413bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (media_size == SupportedMediaSizes[i].media_size) {
423bf66744d61d18c66d46f2608de0467ad3df0268Mopria            strncpy(media_name, SupportedMediaSizes[i].PCL6Name,
433bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    strlen(SupportedMediaSizes[i].PCL6Name));
443bf66744d61d18c66d46f2608de0467ad3df0268Mopria            LOGD("_get_pclm_media_size_name(): match found: %d, %s", media_size, media_name);
453bf66744d61d18c66d46f2608de0467ad3df0268Mopria            break;  // we found a match, so break out of loop
463bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
473bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
483bf66744d61d18c66d46f2608de0467ad3df0268Mopria
493bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (i == SUPPORTED_MEDIA_SIZE_COUNT) {
503bf66744d61d18c66d46f2608de0467ad3df0268Mopria        // media size not found, defaulting to letter
513bf66744d61d18c66d46f2608de0467ad3df0268Mopria        LOGD("_get_pclm_media_size_name(): media size, %d, NOT FOUND, setting to letter",
523bf66744d61d18c66d46f2608de0467ad3df0268Mopria                media_size);
533bf66744d61d18c66d46f2608de0467ad3df0268Mopria        _get_pclm_media_size_name(job_info, US_LETTER, media_name);
543bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
553bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
563bf66744d61d18c66d46f2608de0467ad3df0268Mopria
573bf66744d61d18c66d46f2608de0467ad3df0268Mopria/*
583bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Write a valid media_size into myPageInfo
593bf66744d61d18c66d46f2608de0467ad3df0268Mopria */
603bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic void _get_pclm_media_size(pcl_job_info_t *job_info, media_size_t media_size,
613bf66744d61d18c66d46f2608de0467ad3df0268Mopria        PCLmPageSetup *myPageInfo) {
623bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int i = SUPPORTED_MEDIA_SIZE_COUNT;
633bf66744d61d18c66d46f2608de0467ad3df0268Mopria
643bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (myPageInfo != NULL) {
653bf66744d61d18c66d46f2608de0467ad3df0268Mopria        for (i = 0; i < SUPPORTED_MEDIA_SIZE_COUNT; i++) {
663bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (media_size == SupportedMediaSizes[i].media_size) {
673bf66744d61d18c66d46f2608de0467ad3df0268Mopria                strncpy(myPageInfo->mediaSizeName, SupportedMediaSizes[i].PCL6Name,
683bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        sizeof(myPageInfo->mediaSizeName) - 1);
693bf66744d61d18c66d46f2608de0467ad3df0268Mopria
703bf66744d61d18c66d46f2608de0467ad3df0268Mopria                myPageInfo->mediaWidth = floorf(
713bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        _MI_TO_POINTS(SupportedMediaSizes[i].WidthInInches));
723bf66744d61d18c66d46f2608de0467ad3df0268Mopria                myPageInfo->mediaHeight = floorf(
733bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        _MI_TO_POINTS(SupportedMediaSizes[i].HeightInInches));
743bf66744d61d18c66d46f2608de0467ad3df0268Mopria
753bf66744d61d18c66d46f2608de0467ad3df0268Mopria                LOGD("_get_pclm_media_size(): match found: %d, %s, width=%f, height=%f",
763bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        media_size, SupportedMediaSizes[i].PCL6Name, myPageInfo->mediaWidth,
773bf66744d61d18c66d46f2608de0467ad3df0268Mopria                        myPageInfo->mediaHeight);
783bf66744d61d18c66d46f2608de0467ad3df0268Mopria                break;  // we found a match, so break out of loop
793bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
803bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
813bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
823bf66744d61d18c66d46f2608de0467ad3df0268Mopria
833bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (i == SUPPORTED_MEDIA_SIZE_COUNT) {
843bf66744d61d18c66d46f2608de0467ad3df0268Mopria        // media size not found, defaulting to letter
853bf66744d61d18c66d46f2608de0467ad3df0268Mopria        LOGD("_get_pclm_media_size(): media size, %d, NOT FOUND, setting to letter", media_size);
863bf66744d61d18c66d46f2608de0467ad3df0268Mopria        _get_pclm_media_size(job_info, US_LETTER, myPageInfo);
873bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
883bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
893bf66744d61d18c66d46f2608de0467ad3df0268Mopria
903bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic wJob_t _start_job(wJob_t job_handle, pcl_job_info_t *job_info, media_size_t media_size,
913bf66744d61d18c66d46f2608de0467ad3df0268Mopria        media_type_t media_type, int resolution, duplex_t duplex, duplex_dry_time_t dry_time,
923bf66744d61d18c66d46f2608de0467ad3df0268Mopria        color_space_t color_space, media_tray_t media_tray, float top_margin,
933bf66744d61d18c66d46f2608de0467ad3df0268Mopria        float left_margin) {
943bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int outBuffSize = 0;
953bf66744d61d18c66d46f2608de0467ad3df0268Mopria
963bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (job_info == NULL) {
973bf66744d61d18c66d46f2608de0467ad3df0268Mopria        return _WJOBH_NONE;
983bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
993bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1003bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (job_info->job_handle != _WJOBH_NONE) {
1013bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (job_info->wprint_ifc != NULL) {
1023bf66744d61d18c66d46f2608de0467ad3df0268Mopria            LOGD("_start_job() required cleanup");
1033bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
1043bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->job_handle = _WJOBH_NONE;
1053bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1063bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1073bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if ((job_info->wprint_ifc == NULL) || (job_info->print_ifc == NULL)) {
1083bf66744d61d18c66d46f2608de0467ad3df0268Mopria        return _WJOBH_NONE;
1093bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1103bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1113bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGD("_start_job(), media_size %d, media_type %d, dt %d, %s, media_tray %d margins T %f L %f",
1123bf66744d61d18c66d46f2608de0467ad3df0268Mopria            media_size, media_type, dry_time,
1133bf66744d61d18c66d46f2608de0467ad3df0268Mopria            (duplex == DUPLEX_MODE_NONE) ? "simplex" : "duplex",
1143bf66744d61d18c66d46f2608de0467ad3df0268Mopria            media_tray, top_margin, left_margin);
1153bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1163bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->job_handle = job_handle;
1173bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1183bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _START_JOB(job_info, "pdf");
1193bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1203bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->resolution = resolution;
1213bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->media_size = media_size;
1223bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->standard_scale = (float) resolution / (float) STANDARD_SCALE_FOR_PDF;
1233bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1243bf66744d61d18c66d46f2608de0467ad3df0268Mopria    //  initialize static variables
1253bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_output_buffer = NULL;
1263bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->seed_row = job_info->pcl_buff = NULL;    // unused
1273bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pixel_width = job_info->pixel_height = job_info->page_number = job_info->num_rows = 0;
1283bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1293bf66744d61d18c66d46f2608de0467ad3df0268Mopria    memset((void *) &job_info->pclm_page_info, 0x0, sizeof(PCLmPageSetup));
1303bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _get_pclm_media_size_name(job_info, media_size, &job_info->pclm_page_info.mediaSizeName[0]);
1313bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1323bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if ((left_margin < 0.0f) || (top_margin < 0.0f)) {
1333bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.mediaWidthOffset = 0.0f;
1343bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.mediaHeightOffset = 0.0f;
1353bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else {
1363bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.mediaWidthOffset = (left_margin * (float) STANDARD_SCALE_FOR_PDF);
1373bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.mediaHeightOffset = (top_margin * (float) STANDARD_SCALE_FOR_PDF);
1383bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1393bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1403bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGI("_start_job(), mediaHeightOffsets W %f H %f", job_info->pclm_page_info.mediaWidthOffset,
1413bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->pclm_page_info.mediaHeightOffset);
1423bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1433bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_page_info.pageOrigin = top_left;    // REVISIT
1443bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1453bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->monochrome = (color_space == COLOR_SPACE_MONO);
1463bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_page_info.dstColorSpaceSpefication = deviceRGB;
1473bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (color_space == COLOR_SPACE_MONO) {
1483bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.dstColorSpaceSpefication = grayScale;
1493bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else if (color_space == COLOR_SPACE_COLOR) {
1503bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.dstColorSpaceSpefication = deviceRGB;
1513bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else if (color_space == COLOR_SPACE_ADOBE_RGB) {
1523bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.dstColorSpaceSpefication = adobeRGB;
1533bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1543bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1553bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_page_info.stripHeight = job_info->strip_height;
1563bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_page_info.destinationResolution = res600;
1573bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (resolution == 300) {
1583bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.destinationResolution = res300;
1593bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else if (resolution == 600) {
1603bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.destinationResolution = res600;
1613bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else if (resolution == 1200) {
1623bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.destinationResolution = res1200;
1633bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1643bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1653bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (duplex == DUPLEX_MODE_BOOK) {
1663bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.duplexDisposition = duplex_longEdge;
1673bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else if (duplex == DUPLEX_MODE_TABLET) {
1683bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.duplexDisposition = duplex_shortEdge;
1693bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else {
1703bf66744d61d18c66d46f2608de0467ad3df0268Mopria        job_info->pclm_page_info.duplexDisposition = simplex;
1713bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1723bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1733bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_page_info.mirrorBackside = false;
1743bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclmgen_obj = CreatePCLmGen();
1753bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmStartJob(job_info->pclmgen_obj, (void **) &job_info->pclm_output_buffer, &outBuffSize);
1763bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _WRITE(job_info, (const char *) job_info->pclm_output_buffer, outBuffSize);
1773bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return job_info->job_handle;
1783bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
1793bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1803bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic int _start_page(pcl_job_info_t *job_info, int pixel_width, int pixel_height) {
1813bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmPageSetup *page_info = &job_info->pclm_page_info;
1823bf66744d61d18c66d46f2608de0467ad3df0268Mopria    ubyte *pclm_output_buff = job_info->pclm_output_buffer;
1833bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int outBuffSize = 0;
1843bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1853bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _START_PAGE(job_info, pixel_width, pixel_height);
1863bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1873bf66744d61d18c66d46f2608de0467ad3df0268Mopria    page_info->sourceHeight = (float) pixel_height / job_info->standard_scale;
1883bf66744d61d18c66d46f2608de0467ad3df0268Mopria    page_info->sourceWidth = (float) pixel_width / job_info->standard_scale;
1893bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGI("_start_page(), strip height=%d, image width=%d, image height=%d, scaled width=%f, "
1903bf66744d61d18c66d46f2608de0467ad3df0268Mopria            "scaled height=%f", page_info->stripHeight, pixel_width, pixel_height,
1913bf66744d61d18c66d46f2608de0467ad3df0268Mopria            page_info->sourceWidth, page_info->sourceHeight);
1923bf66744d61d18c66d46f2608de0467ad3df0268Mopria
1933bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (job_info->num_components == 3) {
1943bf66744d61d18c66d46f2608de0467ad3df0268Mopria        page_info->colorContent = color_content;
1953bf66744d61d18c66d46f2608de0467ad3df0268Mopria        page_info->srcColorSpaceSpefication = deviceRGB;
1963bf66744d61d18c66d46f2608de0467ad3df0268Mopria    } else {
1973bf66744d61d18c66d46f2608de0467ad3df0268Mopria        page_info->colorContent = gray_content;
1983bf66744d61d18c66d46f2608de0467ad3df0268Mopria        page_info->srcColorSpaceSpefication = grayScale;
1993bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2003bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2013bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /* Note: we could possibly get this value dynamically from device via IPP (ePCL) however,
2023bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * current ink devices report RLE as the default compression type, which compresses much
2033bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * worse than JPEG or FLATE
2043bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2053bf66744d61d18c66d46f2608de0467ad3df0268Mopria    page_info->compTypeRequested = compressDCT;
2063bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->scan_line_width = pixel_width * job_info->num_components;
2073bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int res1 = PCLmGetMediaDimensions(job_info->pclmgen_obj, page_info->mediaSizeName, page_info);
2083bf66744d61d18c66d46f2608de0467ad3df0268Mopria    page_info->SourceWidthPixels = MIN(pixel_width, job_info->pclm_page_info.mediaWidthInPixels);
2093bf66744d61d18c66d46f2608de0467ad3df0268Mopria    page_info->SourceHeightPixels = pixel_height;
2103bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->pclm_scan_line_width =
2113bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->pclm_page_info.mediaWidthInPixels * job_info->num_components;
2123bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2133bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGD("PCLmGetMediaDimensions(%d), mediaSizeName=%s, mediaheight=%f, mediawidth=%f, "
2143bf66744d61d18c66d46f2608de0467ad3df0268Mopria            "mheightpixels=%d, mwidthpixels=%d", res1, job_info->pclm_page_info.mediaSizeName,
2153bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->pclm_page_info.mediaWidth, job_info->pclm_page_info.mediaHeight,
2163bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->pclm_page_info.mediaWidthInPixels,
2173bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->pclm_page_info.mediaHeightInPixels);
2183bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2193bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmStartPage(job_info->pclmgen_obj, page_info, (void **) &pclm_output_buff, &outBuffSize);
2203bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _WRITE(job_info, (const char *) pclm_output_buff, outBuffSize);
2213bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2223bf66744d61d18c66d46f2608de0467ad3df0268Mopria    job_info->page_number++;
2233bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return job_info->page_number;
2243bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
2253bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2263bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic int _print_swath(pcl_job_info_t *job_info, char *rgb_pixels, int start_row, int num_rows,
2273bf66744d61d18c66d46f2608de0467ad3df0268Mopria        int bytes_per_row) {
2283bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int outBuffSize = 0;
2293bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _PAGE_DATA(job_info, (const unsigned char *) rgb_pixels, (num_rows * bytes_per_row));
2303bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2313bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (job_info->monochrome) {
2323bf66744d61d18c66d46f2608de0467ad3df0268Mopria        unsigned char *buff = (unsigned char *) rgb_pixels;
2333bf66744d61d18c66d46f2608de0467ad3df0268Mopria        int nbytes = (num_rows * bytes_per_row);
2343bf66744d61d18c66d46f2608de0467ad3df0268Mopria        int readIndex, writeIndex;
2353bf66744d61d18c66d46f2608de0467ad3df0268Mopria        for (readIndex = writeIndex = 0; readIndex < nbytes; readIndex += BYTES_PER_PIXEL(1)) {
2363bf66744d61d18c66d46f2608de0467ad3df0268Mopria            unsigned char gray = SP_GRAY(buff[readIndex + 0], buff[readIndex + 1],
2373bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    buff[readIndex + 2]);
2383bf66744d61d18c66d46f2608de0467ad3df0268Mopria            buff[writeIndex++] = gray;
2393bf66744d61d18c66d46f2608de0467ad3df0268Mopria            buff[writeIndex++] = gray;
2403bf66744d61d18c66d46f2608de0467ad3df0268Mopria            buff[writeIndex++] = gray;
2413bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
2423bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2433bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2443bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGD("_print_swath(): page #%d, buffSize=%d, rows %d - %d (%d rows), bytes per row %d",
2453bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->page_number, job_info->strip_height * job_info->scan_line_width, start_row,
2463bf66744d61d18c66d46f2608de0467ad3df0268Mopria            start_row + num_rows - 1, num_rows, bytes_per_row);
2473bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2483bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (job_info->scan_line_width > job_info->pclm_scan_line_width) {
2493bf66744d61d18c66d46f2608de0467ad3df0268Mopria        int i;
2503bf66744d61d18c66d46f2608de0467ad3df0268Mopria        char *src_pixels = rgb_pixels + job_info->scan_line_width;
2513bf66744d61d18c66d46f2608de0467ad3df0268Mopria        char *dest_pixels = rgb_pixels + job_info->pclm_scan_line_width;
2523bf66744d61d18c66d46f2608de0467ad3df0268Mopria        for (i = 1; i < num_rows; i++, src_pixels += job_info->scan_line_width,
2533bf66744d61d18c66d46f2608de0467ad3df0268Mopria                dest_pixels += job_info->pclm_scan_line_width) {
2543bf66744d61d18c66d46f2608de0467ad3df0268Mopria            memmove(dest_pixels, src_pixels, job_info->pclm_scan_line_width);
2553bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
2563bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2573bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2583bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /* if the inBufferSize is ever used in genPCLm, change the input parameter to pass in
2593bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * image_info->printable_width*num_components*strip_height
2603bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * it is currently pixel_width (from _start_page()) * num_components * strip_height
2613bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
2623bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmEncapsulate(job_info->pclmgen_obj, rgb_pixels,
2633bf66744d61d18c66d46f2608de0467ad3df0268Mopria            job_info->strip_height * MIN(job_info->scan_line_width, job_info->pclm_scan_line_width),
2643bf66744d61d18c66d46f2608de0467ad3df0268Mopria            num_rows, (void **) &job_info->pclm_output_buffer, &outBuffSize);
2653bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _WRITE(job_info, (const char *) job_info->pclm_output_buffer, outBuffSize);
2663bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2673bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return OK;
2683bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
2693bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2703bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic int _end_page(pcl_job_info_t *job_info, int page_number) {
2713bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int outBuffSize = 0;
2723bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2733bf66744d61d18c66d46f2608de0467ad3df0268Mopria    if (page_number == -1) {
2743bf66744d61d18c66d46f2608de0467ad3df0268Mopria        LOGI("_end_page(): writing blank page");
2753bf66744d61d18c66d46f2608de0467ad3df0268Mopria        _start_page(job_info, 0, 0);
2762e2be0f9ea6839e000a98ba83daa57c8c3258b6cGlade Diviney        unsigned char blank_data[1] = {0xFF};
2772e2be0f9ea6839e000a98ba83daa57c8c3258b6cGlade Diviney        PCLmEncapsulate(job_info->pclmgen_obj, (void *) blank_data, 1, 1,
2782e2be0f9ea6839e000a98ba83daa57c8c3258b6cGlade Diviney                (void **) &job_info->pclm_output_buffer, &outBuffSize);
2792e2be0f9ea6839e000a98ba83daa57c8c3258b6cGlade Diviney        _WRITE(job_info, (const char *) job_info->pclm_output_buffer, outBuffSize);
2803bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
2813bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGI("_end_page()");
2823bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmEndPage(job_info->pclmgen_obj, (void **) &job_info->pclm_output_buffer, &outBuffSize);
2833bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _WRITE(job_info, (const char *) job_info->pclm_output_buffer, outBuffSize);
2843bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _END_PAGE(job_info);
2853bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2863bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return OK;
2873bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
2883bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2893bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic int _end_job(pcl_job_info_t *job_info) {
2903bf66744d61d18c66d46f2608de0467ad3df0268Mopria    int outBuffSize = 0;
2913bf66744d61d18c66d46f2608de0467ad3df0268Mopria
2923bf66744d61d18c66d46f2608de0467ad3df0268Mopria    LOGI("_end_job()");
2933bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmEndJob(job_info->pclmgen_obj, (void **) &job_info->pclm_output_buffer, &outBuffSize);
2943bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _WRITE(job_info, (const char *) job_info->pclm_output_buffer, outBuffSize);
2953bf66744d61d18c66d46f2608de0467ad3df0268Mopria    PCLmFreeBuffer(job_info->pclmgen_obj, job_info->pclm_output_buffer);
2963bf66744d61d18c66d46f2608de0467ad3df0268Mopria    DestroyPCLmGen(job_info->pclmgen_obj);
2973bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _END_JOB(job_info);
2983bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return OK;
2993bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
3003bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3013bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic bool _canCancelMidPage(void) {
3023bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return false;
3033bf66744d61d18c66d46f2608de0467ad3df0268Mopria}
3043bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3053bf66744d61d18c66d46f2608de0467ad3df0268Mopriastatic const ifc_pcl_t _pcl_ifc = {
3063bf66744d61d18c66d46f2608de0467ad3df0268Mopria    _start_job, _end_job, _start_page, _end_page, _print_swath, _canCancelMidPage
3073bf66744d61d18c66d46f2608de0467ad3df0268Mopria};
3083bf66744d61d18c66d46f2608de0467ad3df0268Mopria
3093bf66744d61d18c66d46f2608de0467ad3df0268Mopriaifc_pcl_t *pclm_connect(void) {
3103bf66744d61d18c66d46f2608de0467ad3df0268Mopria    return ((ifc_pcl_t *) &_pcl_ifc);
3113bf66744d61d18c66d46f2608de0467ad3df0268Mopria}