Camera driver modifications

Added to build jpeg in driver so now allows all android
fuctionality
Removed iLog
Modified credits

Change-Id: I15e10121ed364032ff789a263cb0f1eb8385b61b
This commit is contained in:
KalimochoAz 2011-02-09 18:58:14 +01:00
parent eeb2444cbd
commit 7becc90239
8 changed files with 670 additions and 263 deletions

View File

@ -13,17 +13,18 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:=optional
LOCAL_SRC_FILES:= QualcommCameraHardware.cpp exifwriter.c
LOCAL_SRC_FILES:= QualcommCameraHardware.cpp exifwriter.c jdatadst.cpp jpegConvert.cpp
LOCAL_CFLAGS:= -DDLOPEN_LIBMMCAMERA=$(DLOPEN_LIBMMCAMERA)
LOCAL_C_INCLUDES+= \
vendor/qcom/proprietary/mm-camera/common \
vendor/qcom/proprietary/mm-camera/apps/appslib \
external/jhead \
vendor/qcom/proprietary/mm-camera/jpeg/inc
vendor/qcom/proprietary/mm-camera/common \
vendor/qcom/proprietary/mm-camera/apps/appslib \
external/jhead \
external/jpeg \
vendor/qcom/proprietary/mm-camera/jpeg/inc
LOCAL_SHARED_LIBRARIES:= libbinder libutils libcamera_client liblog
LOCAL_SHARED_LIBRARIES:= libbinder libutils libcamera_client liblog libjpeg
ifneq ($(DLOPEN_LIBMMCAMERA),1)
LOCAL_SHARED_LIBRARIES+= libmmcamera libmm-qcamera-tgt

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
/*
** Copyright 2008, Google Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
@ -28,7 +28,7 @@ extern "C" {
#include "msm_camera.h"
}
#define version "10.12"
#define version "10.12.11"
#define MSM_CAMERA_CONTROL "/dev/msm_camera/msm_camera0"
#define JPEG_EVENT_DONE 0 /* guess */
@ -110,7 +110,7 @@ typedef struct
unsigned int in2_h;
unsigned int out2_w;
unsigned int out2_h;
uint8_t update_flag;
uint8_t update_flag;
} common_crop_t;
typedef struct

186
libcamera/jdatadst.cpp Normal file
View File

@ -0,0 +1,186 @@
/*
* jdatadst.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains compression data destination routines for the case of
* emitting JPEG data to memory.
* While these routines are sufficient for most applications,
* some will want to use a different destination manager.
* IMPORTANT: we assume that fwrite() will correctly transcribe an array of
* unsigned chars into 8-bit-wide elements on external storage. If char is wider
* than 8 bits on your machine, you may need to do some tweaking.
*/
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <jconfig.h>
//#include <jmorecfg.h>
#include <jerror.h>
#include "jdatadst.h"
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
#endif
/* Expanded data destination object for stdio output */
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
/* Expanded data destination object for memory output */
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char ** outbuffer; /* target buffer */
unsigned long * outsize;
unsigned char * newbuffer; /* newly allocated buffer */
unsigned char * buffer; /* start of buffer */
size_t bufsize;
} my_mem_destination_mgr;
typedef my_mem_destination_mgr * my_mem_dest_ptr;
/*
* Initialize destination --- called by jpeg_start_compress
* before any data is actually written.
*/
METHODDEF(void)
init_mem_destination (j_compress_ptr cinfo)
{
/* no work necessary here */
}
/*
* Empty the output buffer --- called whenever buffer fills up.
*
* In typical applications, this should write the entire output buffer
* (ignoring the current state of next_output_byte & free_in_buffer),
* reset the pointer & count to the start of the buffer, and return TRUE
* indicating that the buffer has been dumped.
*
* In applications that need to be able to suspend compression due to output
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
* In this situation, the compressor will return to its caller (possibly with
* an indication that it has not accepted all the supplied scanlines). The
* application should resume compression after it has made more room in the
* output buffer. Note that there are substantial restrictions on the use of
* suspension --- see the documentation.
*
* When suspending, the compressor will back up to a convenient restart point
* (typically the start of the current MCU). next_output_byte & free_in_buffer
* indicate where the restart point will be if the current call returns FALSE.
* Data beyond this point will be regenerated after resumption, so do not
* write it out when emptying the buffer externally.
*/
METHODDEF(boolean)
empty_mem_output_buffer (j_compress_ptr cinfo)
{
size_t nextsize;
unsigned char * nextbuffer;
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
/* Try to allocate new buffer with double size */
nextsize = dest->bufsize * 2;
nextbuffer = (unsigned char *)malloc(nextsize);
if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
if (dest->newbuffer != NULL)
free(dest->newbuffer);
dest->newbuffer = nextbuffer;
dest->pub.next_output_byte = nextbuffer + dest->bufsize;
dest->pub.free_in_buffer = dest->bufsize;
dest->buffer = nextbuffer;
dest->bufsize = nextsize;
return TRUE;
}
/*
* Terminate destination --- called by jpeg_finish_compress
* after all data has been written. Usually needs to flush buffer.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
METHODDEF(void)
term_mem_destination (j_compress_ptr cinfo)
{
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
*dest->outbuffer = dest->buffer;
*dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
}
/*
* Prepare for output to a memory buffer.
* The caller may supply an own initial buffer with appropriate size.
* Otherwise, or when the actual data output exceeds the given size,
* the library adapts the buffer size as necessary.
* The standard library functions malloc/free are used for allocating
* larger memory, so the buffer is available to the application after
* finishing compression, and then the application is responsible for
* freeing the requested memory.
*/
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer, unsigned long * outsize)
{
my_mem_dest_ptr dest;
if (outbuffer == NULL || outsize == NULL) /* sanity check */
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same buffer without re-executing jpeg_mem_dest.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_mem_destination_mgr));
}
dest = (my_mem_dest_ptr) cinfo->dest;
dest->pub.init_destination = init_mem_destination;
dest->pub.empty_output_buffer = empty_mem_output_buffer;
dest->pub.term_destination = term_mem_destination;
dest->outbuffer = outbuffer;
dest->outsize = outsize;
dest->newbuffer = NULL;
if (*outbuffer == NULL || *outsize == 0) {
/* Allocate initial buffer */
dest->newbuffer = *outbuffer = (unsigned char *)malloc(OUTPUT_BUF_SIZE);
if (dest->newbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
*outsize = OUTPUT_BUF_SIZE;
}
dest->pub.next_output_byte = dest->buffer = *outbuffer;
dest->pub.free_in_buffer = dest->bufsize = *outsize;
}

53
libcamera/jdatadst.h Normal file
View File

@ -0,0 +1,53 @@
/*
* jdatadst.h
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines backported from jpeglib 8 for writing
* jpeg data directly to memory.
*/
#ifndef JDATADST_H
#define JDATADST_H
/*
* First we include the configuration files that record how this
* installation of the JPEG library is set up. jconfig.h can be
* generated automatically for many systems. jmorecfg.h contains
* manual configuration options that most people need not worry about.
*/
#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
#include <jconfig.h> /* widely used configuration options */
#endif
//#include <jmorecfg.h> /* seldom changed options */
#include <string.h>
extern "C" {
/* Declarations for routines called by application.
* The JPP macro hides prototype parameters from compilers that can't cope.
* Note JPP requires double parentheses.
*/
#ifdef HAVE_PROTOTYPES
#define JPP(arglist) arglist
#else
#define JPP(arglist) ()
#endif
/* Data source and destination managers: memory buffers. */
EXTERN(void) jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer,
unsigned long * outsize);
} // extern "C"
#define SIZEOF(object) ((size_t) sizeof(object))
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
#endif /* JPEGLIB_H */

167
libcamera/jpegConvert.cpp Normal file
View File

@ -0,0 +1,167 @@
/*
Version: 1.0
Coded by: Josebagar <joseba.gar@gmail.com> 02/2011 (linux version)
Revised and Recoded: KalimochoAz <calimochoazucarado@gmail.com> 02/2011 (android conversions) Done for CyanogenMOD
Free code: feel free to use, copy, modify or criticize. But please leave it as free code always
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
extern "C" {
#include <jpeglib.h>
}
#if JPEG_LIB_VERSION < 80
// The routines defined in this file have been backported from jpeglib 8.0
#include "jdatadst.h"
#endif
#include "jpegConvert.h"
#include "raw2jpeg.h"
////////////////////////////////////////////////////////////////////////////////
YuvToJpegEncoder* YuvToJpegEncoder::create(int* strides) {
// Only ImageFormat.NV21 and ImageFormat.YUY2 are supported
// for now.
return new Yuv420SpToJpegEncoder(strides);
}
YuvToJpegEncoder::YuvToJpegEncoder(int* strides) : fStrides(strides) {
}
bool YuvToJpegEncoder::encode(unsigned char* dest, void* inYuv, int width,
int height, int* offsets, int jpegQuality) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
long unsigned int image_size;
unsigned char* ucDest;
// Warning, this is ONLY valid for YUV420SP (ImageFormat.NV21 in android)
image_size = (width*height*1.5);
// Create JPEG compression object
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
// Point it to the output file
jpeg_mem_dest(&cinfo, &dest, &image_size);
setJpegCompressStruct(&cinfo, width, height, jpegQuality);
jpeg_start_compress(&cinfo, TRUE);
compress(&cinfo, (uint8_t*) inYuv, offsets);
jpeg_finish_compress(&cinfo);
return true;
}
void YuvToJpegEncoder::setJpegCompressStruct(jpeg_compress_struct* cinfo,
int width, int height, int quality) {
cinfo->image_width = width;
cinfo->image_height = height;
cinfo->input_components = 3;
cinfo->in_color_space = JCS_YCbCr;
jpeg_set_defaults(cinfo);
jpeg_set_quality(cinfo, quality, TRUE);
jpeg_set_colorspace(cinfo, JCS_YCbCr);
cinfo->raw_data_in = TRUE;
cinfo->dct_method = JDCT_IFAST;
configSamplingFactors(cinfo);
}
///////////////////////////////////////////////////////////////////
Yuv420SpToJpegEncoder::Yuv420SpToJpegEncoder(int* strides) :
YuvToJpegEncoder(strides) {
fNumPlanes = 2;
}
void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
uint8_t* yuv, int* offsets) {
JSAMPROW y[16];
JSAMPROW cb[8];
JSAMPROW cr[8];
JSAMPARRAY planes[3];
planes[0] = y;
planes[1] = cb;
planes[2] = cr;
int width = cinfo->image_width;
int height = cinfo->image_height;
uint8_t* yPlanar = yuv + offsets[0];
uint8_t* vuPlanar = yuv + offsets[1]; //width * height;
uint8_t* uRows = new uint8_t [8 * (width >> 1)];
uint8_t* vRows = new uint8_t [8 * (width >> 1)];
// process 16 lines of Y and 8 lines of U/V each time.
while (cinfo->next_scanline < cinfo->image_height) {
//deitnerleave u and v
deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width);
for (int i = 0; i < 16; i++) {
// y row
y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
// construct u row and v row
if ((i & 1) == 0) {
// height and width are both halved because of downsampling
int offset = (i >> 1) * (width >> 1);
cb[i/2] = uRows + offset;
cr[i/2] = vRows + offset;
}
}
jpeg_write_raw_data(cinfo, planes, 16);
}
delete [] uRows;
delete [] vRows;
}
void Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows,
uint8_t* vRows, int rowIndex, int width) {
for (int row = 0; row < 8; ++row) {
int offset = ((rowIndex >> 1) + row) * fStrides[1];
uint8_t* vu = vuPlanar + offset;
for (int i = 0; i < (width >> 1); ++i) {
int index = row * (width >> 1) + i;
uRows[index] = vu[1];
vRows[index] = vu[0];
vu += 2;
}
}
}
void Yuv420SpToJpegEncoder::configSamplingFactors(jpeg_compress_struct* cinfo) {
// cb and cr are horizontally downsampled and vertically downsampled as well.
cinfo->comp_info[0].h_samp_factor = 2;
cinfo->comp_info[0].v_samp_factor = 2;
cinfo->comp_info[1].h_samp_factor = 1;
cinfo->comp_info[1].v_samp_factor = 1;
cinfo->comp_info[2].h_samp_factor = 1;
cinfo->comp_info[2].v_samp_factor = 1;
}
///////////////////////////////////////////////////////////////////////////////
int yuv420_save2jpeg(unsigned char *dest, void *src, int width, int height, int quality) {
int imgStrides[2], imgOffsets[2];
// Convert the RAW data to JPEG
imgStrides[0] = imgStrides[1] = width;
YuvToJpegEncoder* encoder = YuvToJpegEncoder::create(imgStrides);
if (encoder == NULL) {
return false;
}
// Guessed from frameworks/base/graphics/java/android/graphics/YuvImage.java
// in android
imgOffsets[0] = 0;
imgOffsets[1] = width*height;
encoder->encode(dest, src, width, height, imgOffsets, quality);
delete encoder;
return true;
}

60
libcamera/jpegConvert.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef YuvToJpegEncoder_DEFINED
#define YuvToJpegEncoder_DEFINED
extern "C" {
#include "jpeglib.h"
#include "jerror.h"
}
class YuvToJpegEncoder {
public:
/** Create an encoder based on the YUV format.
*
* @param pixelFormat The yuv pixel format as defined in ui/PixelFormat.h.
* @param strides The number of row bytes in each image plane.
* @return an encoder based on the pixelFormat.
*/
static YuvToJpegEncoder* create(int* strides);
YuvToJpegEncoder(int* strides);
/** Encode YUV data to jpeg, which is output to a stream.
*
* @param dest The jpeg output stream.
* @param inYuv The input yuv data.
* @param width Width of the the Yuv data in terms of pixels.
* @param height Height of the Yuv data in terms of pixels.
* @param offsets The offsets in each image plane with respect to inYuv.
* @param jpegQuality Picture quality in [0, 100].
* @return true if successfully compressed the stream.
*/
bool encode(unsigned char* dest, void* inYuv, int width,
int height, int* offsets, int jpegQuality);
virtual ~YuvToJpegEncoder() {}
protected:
int fNumPlanes;
int* fStrides;
void setJpegCompressStruct(jpeg_compress_struct* cinfo, int width,
int height, int quality);
virtual void configSamplingFactors(jpeg_compress_struct* cinfo) = 0;
virtual void compress(jpeg_compress_struct* cinfo,
uint8_t* yuv, int* offsets) = 0;
};
class Yuv420SpToJpegEncoder : public YuvToJpegEncoder {
public:
Yuv420SpToJpegEncoder(int* strides);
virtual ~Yuv420SpToJpegEncoder() {}
private:
void configSamplingFactors(jpeg_compress_struct* cinfo);
void deinterleaveYuv(uint8_t* yuv, int width, int height,
uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar);
void deinterleave(uint8_t* vuPlanar, uint8_t* uRows, uint8_t* vRows,
int rowIndex, int width);
void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets);
};
#endif

1
libcamera/raw2jpeg.h Normal file
View File

@ -0,0 +1 @@
int yuv420_save2jpeg(unsigned char *dest, void *src, int width, int height, int quality);