1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <memory> 19 #include <functional> 20 21 /* 22 * Provides a wrapper around libjpeg. 23 */ 24 namespace jpegutil { 25 26 /** 27 * Represents a model for accessing pixel data for a single plane of an image. 28 * Note that the actual data is not owned by this class, and the underlying 29 * data does not need to be stored in separate planes. 30 */ 31 class Plane { 32 public: 33 /** 34 * Provides access to several rows of planar data at a time, copied into an 35 * intermediate buffer with pixel data packed in contiguous rows which can be 36 * passed to libjpeg. 37 */ 38 class RowIterator { 39 public: 40 RowIterator(const Plane* plane); 41 42 /** 43 * Retrieves the y-th row, copying it into a buffer with as much padding 44 * as is necessary for use with libjpeg. 45 */ 46 unsigned char* operator()(int y); 47 48 private: 49 const Plane* plane_; 50 51 // Stores a ring-buffer of cache-aligned buffers for storing contiguous 52 // pixel data for rows of the image to be sent to libjpeg. 53 std::unique_ptr<unsigned char[]> buffer_; 54 // The cache-aligned start index of buffer_ 55 unsigned char* alignedBuffer_; 56 // The total number of rows in the ring-buffer 57 int bufRowCount_; 58 // The current ring-buffer row being used 59 int bufCurRow_; 60 // The number of bytes between consecutive rows in the buffer 61 int bufRowStride_; 62 63 // The number of bytes of padding-pixels which must be appended to each row 64 // to reach the multiple of 16-bytes required by libjpeg. 65 int rowPadding_; 66 }; 67 68 Plane(int imgWidth, int imgHeight, int planeWidth, int planeHeight, 69 unsigned char* data, int pixelStride, int rowStride); 70 71 int imgWidth() const { return imgWidth_; } 72 int imgHeight() const { return imgHeight_; } 73 74 private: 75 // The dimensions of the entire image 76 int imgWidth_; 77 int imgHeight_; 78 // The dimensions of this plane of the image 79 int planeWidth_; 80 int planeHeight_; 81 82 // A pointer to raw pixel data 83 unsigned char* data_; 84 // The difference in address between the start of consecutive rows 85 int rowStride_; 86 // The difference in address between consecutive pixels in the same row 87 int pixelStride_; 88 }; 89 90 /** 91 * Compresses an image from YUV 420p to JPEG. Output is buffered in outBuf until 92 * capacity is reached, at which point flush(size_t) is called to write 93 * out the specified number of bytes from outBuf. Returns the number of bytes 94 * written, or -1 in case of an error. 95 */ 96 int compress(const Plane& yPlane, const Plane& cbPlane, const Plane& crPlane, 97 unsigned char* outBuf, size_t outBufCapacity, 98 std::function<void(size_t)> flush, int quality); 99 } 100