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