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 <stdio.h> 20 #include "common_defines.h" 21 #include <wprint_debug.h> 22 23 extern "C" 24 { 25 #include <jpeglib.h> 26 } 27 28 #define TAG "genJPEGStrips" 29 30 /* 31 * Function for setting up the buffer (which we already did) 32 */ 33 static void init_buffer(jpeg_compress_struct *) { 34 } 35 36 /* 37 * Function for handling buffer overlow (should not happen because we allocated a large 38 * buffer) 39 */ 40 static boolean empty_buffer(jpeg_compress_struct *) { 41 return TRUE; 42 } 43 44 /* 45 * Function for finalizing the buffer (which we do not need to do) 46 */ 47 static void term_buffer(jpeg_compress_struct *) { 48 } 49 50 GLOBAL(void) 51 write_JPEG_Buff(ubyte *buffPtr, int quality, int image_width, int image_height, 52 JSAMPLE *imageBuffer, int resolution, colorSpaceDisposition destCS, int *numCompBytes) { 53 struct jpeg_error_mgr jerr; 54 55 // Step 1: allocate and initialize JPEG compression object 56 struct jpeg_compress_struct cinfo = { 57 .client_data = NULL, .err = jpeg_std_error(&jerr) 58 }; 59 60 // Now we can initialize the JPEG compression object. 61 jpeg_create_compress(&cinfo); 62 63 // Step 2: specify data destination (we will use a memory buffer) 64 struct jpeg_destination_mgr dm = { 65 .init_destination = init_buffer, .empty_output_buffer = empty_buffer, 66 .term_destination = term_buffer, .next_output_byte = buffPtr, 67 .free_in_buffer = (size_t) image_width * image_height * 3 68 }; 69 cinfo.dest = &dm; 70 71 // Step 3: set parameters for compression 72 73 cinfo.image_width = (JDIMENSION) image_width; 74 cinfo.image_height = (JDIMENSION) image_height; 75 if (destCS == deviceRGB || destCS == adobeRGB) { 76 cinfo.in_color_space = JCS_RGB; 77 cinfo.jpeg_color_space = JCS_RGB; 78 cinfo.input_components = 3; 79 } else { 80 cinfo.in_color_space = JCS_GRAYSCALE; 81 cinfo.jpeg_color_space = JCS_GRAYSCALE; 82 cinfo.input_components = 1; 83 } 84 85 jpeg_set_defaults(&cinfo); 86 87 /* Now you can set any non-default parameters you wish to. 88 * Here we just illustrate the use of quality (quantization table) scaling: 89 */ 90 jpeg_set_quality(&cinfo, quality, TRUE); // TRUE = limit to baseline-JPEG values 91 92 // Set the density so that the JFIF header has the correct settings 93 cinfo.density_unit = 1; // 1=dots-per-inch, 2=dots per cm 94 cinfo.X_density = (UINT16) resolution; 95 cinfo.Y_density = (UINT16) resolution; 96 97 // set the rows/columns setting to reflect the resolution 98 // MCU = Minimum Coded Unit 99 cinfo.MCUs_per_row = (JDIMENSION) image_width; 100 cinfo.MCU_rows_in_scan = (JDIMENSION) image_height; 101 102 // Step 4: Start compressor 103 jpeg_start_compress(&cinfo, TRUE); 104 105 // Step 5: Write scanlines 106 107 int row_stride; // physical row width in image buffer 108 row_stride = image_width * cinfo.input_components; // JSAMPLEs per row in imageBuffer 109 110 JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s] 111 while (cinfo.next_scanline < cinfo.image_height) { 112 row_pointer[0] = &imageBuffer[cinfo.next_scanline * row_stride]; 113 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); 114 } 115 116 // Step 6: Finish compression 117 118 jpeg_finish_compress(&cinfo); 119 120 // Step 7: release JPEG compression object 121 122 jpeg_destroy_compress(&cinfo); 123 124 *numCompBytes = (int) (cinfo.dest->next_output_byte - buffPtr); 125 126 LOGD("write_JPEG_Buff: w=%d, h=%d, r=%d, q=%d compressed to %d", image_width, image_height, 127 resolution, quality, *numCompBytes); 128 }