mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-08 01:36:47 +08:00
JPEG use new/delete instead of scoped pointer
BUG=none TEST=jpeg still runs ok Review URL: https://webrtc-codereview.appspot.com/456006 git-svn-id: http://libyuv.googlecode.com/svn/trunk@225 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
74b50f1b89
commit
e2a55aff59
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 224
|
||||
Version: 225
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#define INCLUDE_LIBYUV_MJPEG_DECODER_H_
|
||||
|
||||
#include "libyuv/basic_types.h"
|
||||
#include "libyuv/scoped_ptr.h"
|
||||
|
||||
struct jpeg_common_struct;
|
||||
struct jpeg_decompress_struct;
|
||||
@ -164,9 +163,9 @@ class MJpegDecoder {
|
||||
Buffer buf_;
|
||||
BufferVector buf_vec_;
|
||||
|
||||
libyuv::scoped_ptr<jpeg_decompress_struct> decompress_struct_;
|
||||
libyuv::scoped_ptr<jpeg_source_mgr> source_mgr_;
|
||||
libyuv::scoped_ptr<SetJmpErrorMgr> error_mgr_;
|
||||
jpeg_decompress_struct* decompress_struct_;
|
||||
jpeg_source_mgr* source_mgr_;
|
||||
SetJmpErrorMgr* error_mgr_;
|
||||
|
||||
// true iff at least one component has scanline padding. (i.e.,
|
||||
// GetComponentScanlinePadding() != 0.)
|
||||
|
||||
@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The LibYuv project authors. All Rights Reserved.
|
||||
* Copyright (c) 2001, 2002 Peter Dimov
|
||||
* Copyright (c) 1998, 1999 Greg Colvin and Beman Dawes
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*
|
||||
* Permission to copy, use, modify, sell and distribute this software
|
||||
* is granted provided this copyright notice appears in all copies.
|
||||
* This software is provided "as is" without express or implied
|
||||
* warranty, and with no claim as to its suitability for any purpose.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
|
||||
*
|
||||
* scoped_ptr mimics a built-in pointer except that it guarantees deletion
|
||||
* of the object pointed to, either on destruction of the scoped_ptr or via
|
||||
* an explicit reset(). scoped_ptr is a simple solution for simple needs;
|
||||
* use shared_ptr or std::auto_ptr if your needs are more complex.
|
||||
*
|
||||
* scoped_ptr_malloc added in by Google. When one of
|
||||
* these goes out of scope, instead of doing a delete or delete[], it
|
||||
* calls free(). scoped_ptr_malloc<char> is likely to see much more
|
||||
* use than any other specializations.
|
||||
*
|
||||
* release() added in by Google. Use this to conditionally
|
||||
* transfer ownership of a heap-allocated object to the caller, usually on
|
||||
* method success.
|
||||
*/
|
||||
|
||||
// TODO(fbarchard): move into source as implementation detail
|
||||
|
||||
#ifndef INCLUDE_LIBYUV_SCOPED_PTR_H_
|
||||
#define INCLUDE_LIBYUV_SCOPED_PTR_H_
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <stdlib.h> // for free() decl
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace std { using ::ptrdiff_t; };
|
||||
#endif // _WIN32
|
||||
|
||||
namespace libyuv {
|
||||
|
||||
template <typename T>
|
||||
class scoped_ptr {
|
||||
private:
|
||||
|
||||
T* ptr;
|
||||
|
||||
scoped_ptr(scoped_ptr const &);
|
||||
scoped_ptr & operator=(scoped_ptr const &);
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr(T* p = NULL): ptr(p) {}
|
||||
|
||||
~scoped_ptr() {
|
||||
typedef char type_must_be_complete[sizeof(T)];
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
void reset(T* p = NULL) {
|
||||
typedef char type_must_be_complete[sizeof(T)];
|
||||
|
||||
if (ptr != p) {
|
||||
T* obj = ptr;
|
||||
ptr = p;
|
||||
// Delete last, in case obj destructor indirectly results in ~scoped_ptr
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void swap(scoped_ptr & b) {
|
||||
T* tmp = b.ptr;
|
||||
b.ptr = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
T* release() {
|
||||
T* tmp = ptr;
|
||||
ptr = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T** accept() {
|
||||
if (ptr) {
|
||||
delete ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
return &ptr;
|
||||
}
|
||||
|
||||
T** use() {
|
||||
return &ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> inline
|
||||
void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
|
||||
// is guaranteed, either on destruction of the scoped_array or via an explicit
|
||||
// reset(). Use shared_array or std::vector if your needs are more complex.
|
||||
|
||||
template<typename T>
|
||||
class scoped_array {
|
||||
private:
|
||||
|
||||
T* ptr;
|
||||
|
||||
scoped_array(scoped_array const &);
|
||||
scoped_array & operator=(scoped_array const &);
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_array(T* p = NULL) : ptr(p) {}
|
||||
|
||||
~scoped_array() {
|
||||
typedef char type_must_be_complete[sizeof(T)];
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
void reset(T* p = NULL) {
|
||||
typedef char type_must_be_complete[sizeof(T)];
|
||||
|
||||
if (ptr != p) {
|
||||
T* arr = ptr;
|
||||
ptr = p;
|
||||
// Delete last, in case arr destructor indirectly results in ~scoped_array
|
||||
delete [] arr;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator[](std::ptrdiff_t i) const {
|
||||
return ptr[i];
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void swap(scoped_array & b) {
|
||||
T* tmp = b.ptr;
|
||||
b.ptr = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
T* release() {
|
||||
T* tmp = ptr;
|
||||
ptr = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T** accept() {
|
||||
if (ptr) {
|
||||
delete [] ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
return &ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> inline
|
||||
void swap(scoped_array<T>& a, scoped_array<T>& b) {
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
|
||||
// second template argument, the function used to free the object.
|
||||
|
||||
template<typename T, void (*FF)(void*) = free> class scoped_ptr_malloc {
|
||||
private:
|
||||
|
||||
T* ptr;
|
||||
|
||||
scoped_ptr_malloc(scoped_ptr_malloc const &);
|
||||
scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
|
||||
|
||||
~scoped_ptr_malloc() {
|
||||
FF(static_cast<void*>(ptr));
|
||||
}
|
||||
|
||||
void reset(T* p = 0) {
|
||||
if (ptr != p) {
|
||||
FF(static_cast<void*>(ptr));
|
||||
ptr = p;
|
||||
}
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void swap(scoped_ptr_malloc & b) {
|
||||
T* tmp = b.ptr;
|
||||
b.ptr = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
T* release() {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T** accept() {
|
||||
if (ptr) {
|
||||
FF(static_cast<void*>(ptr));
|
||||
ptr = 0;
|
||||
}
|
||||
return &ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, void (*FF)(void*)> inline
|
||||
void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace libyuv
|
||||
|
||||
#endif // INCLUDE_LIBYUV_SCOPED_PTR_H_
|
||||
@ -11,7 +11,7 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define INCLUDE_LIBYUV_VERSION 223
|
||||
#define INCLUDE_LIBYUV_VERSION 225
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
|
||||
@ -16,22 +16,13 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
// jpeglib defines INT32 with a definition that conflicts with the one
|
||||
// in the Vista platforms SDK. By defining XMD_H, it skips its definition of
|
||||
// INT16 and INT32 and we can define them ourself the Windows way.
|
||||
#define XMD_H
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include <jpeglib.h>
|
||||
}
|
||||
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
namespace libyuv {
|
||||
|
||||
struct SetJmpErrorMgr {
|
||||
@ -53,9 +44,9 @@ MJpegDecoder::MJpegDecoder()
|
||||
scanlines_sizes_(NULL),
|
||||
databuf_(NULL),
|
||||
databuf_strides_(NULL) {
|
||||
decompress_struct_.reset(new jpeg_decompress_struct);
|
||||
source_mgr_.reset(new jpeg_source_mgr);
|
||||
error_mgr_.reset(new SetJmpErrorMgr);
|
||||
decompress_struct_ = new jpeg_decompress_struct;
|
||||
source_mgr_ = new jpeg_source_mgr;
|
||||
error_mgr_ = new SetJmpErrorMgr;
|
||||
decompress_struct_->err = jpeg_std_error(&error_mgr_->base);
|
||||
// Override standard exit()-based error handler.
|
||||
error_mgr_->base.error_exit = &ErrorHandler;
|
||||
@ -65,14 +56,17 @@ MJpegDecoder::MJpegDecoder()
|
||||
source_mgr_->skip_input_data = &skip_input_data;
|
||||
source_mgr_->resync_to_restart = &jpeg_resync_to_restart;
|
||||
source_mgr_->term_source = &term_source;
|
||||
jpeg_create_decompress(decompress_struct_.get());
|
||||
decompress_struct_->src = source_mgr_.get();
|
||||
jpeg_create_decompress(decompress_struct_);
|
||||
decompress_struct_->src = source_mgr_;
|
||||
buf_vec_.buffers = &buf_;
|
||||
buf_vec_.len = 1;
|
||||
}
|
||||
|
||||
MJpegDecoder::~MJpegDecoder() {
|
||||
jpeg_destroy_decompress(decompress_struct_.get());
|
||||
jpeg_destroy_decompress(decompress_struct_);
|
||||
delete decompress_struct_;
|
||||
delete source_mgr_;
|
||||
delete error_mgr_;
|
||||
DestroyOutputBuffers();
|
||||
}
|
||||
|
||||
@ -114,7 +108,7 @@ bool MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) {
|
||||
}
|
||||
|
||||
buf_.data = src;
|
||||
buf_.len = src_len;
|
||||
buf_.len = static_cast<int>(src_len);
|
||||
buf_vec_.pos = 0;
|
||||
decompress_struct_->client_data = &buf_vec_;
|
||||
if (setjmp(error_mgr_->setjmp_buffer)) {
|
||||
@ -122,7 +116,7 @@ bool MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) {
|
||||
// longjmp() and rewound the stack to here. Return error.
|
||||
return false;
|
||||
}
|
||||
if (jpeg_read_header(decompress_struct_.get(), TRUE) != JPEG_HEADER_OK) {
|
||||
if (jpeg_read_header(decompress_struct_, TRUE) != JPEG_HEADER_OK) {
|
||||
// ERROR: Bad MJPEG header
|
||||
return false;
|
||||
}
|
||||
@ -242,7 +236,7 @@ bool MJpegDecoder::UnloadFrame() {
|
||||
// longjmp() and rewound the stack to here. Return error.
|
||||
return false;
|
||||
}
|
||||
jpeg_abort_decompress(decompress_struct_.get());
|
||||
jpeg_abort_decompress(decompress_struct_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -298,11 +292,11 @@ bool MJpegDecoder::DecodeToBuffers(
|
||||
for (int i = 0; i < num_outbufs_; ++i) {
|
||||
// TODO(fbarchard): Compute skip to avoid this
|
||||
assert(skip % GetVertSubSampFactor(i) == 0);
|
||||
int scanlines_to_skip =
|
||||
int rows_to_skip =
|
||||
DivideAndRoundDown(skip, GetVertSubSampFactor(i));
|
||||
int scanlines_to_copy = GetComponentScanlinesPerImcuRow(i) -
|
||||
scanlines_to_skip;
|
||||
int data_to_skip = scanlines_to_skip * GetComponentStride(i);
|
||||
rows_to_skip;
|
||||
int data_to_skip = rows_to_skip * GetComponentStride(i);
|
||||
CopyRows(databuf_[i] + data_to_skip, GetComponentStride(i),
|
||||
planes[i], GetComponentWidth(i), scanlines_to_copy);
|
||||
planes[i] += scanlines_to_copy * GetComponentWidth(i);
|
||||
@ -380,8 +374,8 @@ bool MJpegDecoder::DecodeToCallback(CallbackFunction fn, void* opaque,
|
||||
for (int i = 0; i < num_outbufs_; ++i) {
|
||||
// TODO(fbarchard): Compute skip to avoid this
|
||||
assert(skip % GetVertSubSampFactor(i) == 0);
|
||||
int scanlines_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i));
|
||||
int data_to_skip = scanlines_to_skip * GetComponentStride(i);
|
||||
int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i));
|
||||
int data_to_skip = rows_to_skip * GetComponentStride(i);
|
||||
// Change our own data buffer pointers so we can pass them to the
|
||||
// callback.
|
||||
databuf_[i] += data_to_skip;
|
||||
@ -390,8 +384,8 @@ bool MJpegDecoder::DecodeToCallback(CallbackFunction fn, void* opaque,
|
||||
(*fn)(opaque, databuf_, databuf_strides_, scanlines_to_copy);
|
||||
// Now change them back.
|
||||
for (int i = 0; i < num_outbufs_; ++i) {
|
||||
int scanlines_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i));
|
||||
int data_to_skip = scanlines_to_skip * GetComponentStride(i);
|
||||
int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i));
|
||||
int data_to_skip = rows_to_skip * GetComponentStride(i);
|
||||
databuf_[i] -= data_to_skip;
|
||||
}
|
||||
lines_left -= scanlines_to_copy;
|
||||
@ -422,7 +416,7 @@ void MJpegDecoder::init_source(j_decompress_ptr cinfo) {
|
||||
}
|
||||
|
||||
boolean MJpegDecoder::fill_input_buffer(j_decompress_ptr cinfo) {
|
||||
BufferVector *buf_vec = static_cast<BufferVector *>(cinfo->client_data);
|
||||
BufferVector* buf_vec = static_cast<BufferVector*>(cinfo->client_data);
|
||||
if (buf_vec->pos >= buf_vec->len) {
|
||||
assert(0 && "No more data");
|
||||
// ERROR: No more data
|
||||
@ -434,7 +428,8 @@ boolean MJpegDecoder::fill_input_buffer(j_decompress_ptr cinfo) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void MJpegDecoder::skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
|
||||
void MJpegDecoder::skip_input_data(j_decompress_ptr cinfo,
|
||||
long num_bytes) { // NOLINT
|
||||
cinfo->src->next_input_byte += num_bytes;
|
||||
}
|
||||
|
||||
@ -453,7 +448,7 @@ void MJpegDecoder::ErrorHandler(j_common_ptr cinfo) {
|
||||
(*cinfo->err->format_message)(cinfo, buf);
|
||||
// ERROR: Error in jpeglib: buf
|
||||
|
||||
SetJmpErrorMgr *mgr = reinterpret_cast<SetJmpErrorMgr *>(cinfo->err);
|
||||
SetJmpErrorMgr* mgr = reinterpret_cast<SetJmpErrorMgr*>(cinfo->err);
|
||||
// This rewinds the call stack to the point of the corresponding setjmp()
|
||||
// and causes it to return (for a second time) with value 1.
|
||||
longjmp(mgr->setjmp_buffer, 1);
|
||||
@ -507,7 +502,7 @@ bool MJpegDecoder::StartDecode() {
|
||||
decompress_struct_->enable_2pass_quant = false; // Only for buffered mode
|
||||
decompress_struct_->do_block_smoothing = false; // blocky but fast
|
||||
|
||||
if (!jpeg_start_decompress(decompress_struct_.get())) {
|
||||
if (!jpeg_start_decompress(decompress_struct_)) {
|
||||
// ERROR: Couldn't start JPEG decompressor";
|
||||
return false;
|
||||
}
|
||||
@ -517,7 +512,7 @@ bool MJpegDecoder::StartDecode() {
|
||||
bool MJpegDecoder::FinishDecode() {
|
||||
// jpeglib considers it an error if we finish without decoding the whole
|
||||
// image, so we call "abort" rather than "finish".
|
||||
jpeg_abort_decompress(decompress_struct_.get());
|
||||
jpeg_abort_decompress(decompress_struct_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -533,7 +528,7 @@ void MJpegDecoder::SetScanlinePointers(uint8** data) {
|
||||
|
||||
inline bool MJpegDecoder::DecodeImcuRow() {
|
||||
return static_cast<unsigned int>(GetImageScanlinesPerImcuRow()) ==
|
||||
jpeg_read_raw_data(decompress_struct_.get(),
|
||||
jpeg_read_raw_data(decompress_struct_,
|
||||
scanlines_,
|
||||
GetImageScanlinesPerImcuRow());
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user