⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegimagedecoder.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2006 Apple Computer, Inc. * Copyright (C) 2008, 2009 Google, Inc. * * Portions are Copyright (C) 2001-6 mozilla.org * * Other contributors: *   Stuart Parmenter <stuart@mozilla.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * * Alternatively, the contents of this file may be used under the terms * of either the Mozilla Public License Version 1.1, found at * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html * (the "GPL"), in which case the provisions of the MPL or the GPL are * applicable instead of those above.  If you wish to allow use of your * version of this file only under the terms of one of those two * licenses (the MPL or the GPL) and not to allow others to use your * version of this file under the LGPL, indicate your decision by * deletingthe provisions above and replace them with the notice and * other provisions required by the MPL or the GPL, as the case may be. * If you do not delete the provisions above, a recipient may use your * version of this file under any of the LGPL, the MPL or the GPL. */#include "config.h"#include "JPEGImageDecoder.h"#include <assert.h>extern "C" {#include "jpeglib.h"}#include <setjmp.h>namespace WebCore {struct decoder_error_mgr {    struct jpeg_error_mgr pub;  /* "public" fields for IJG library*/    jmp_buf setjmp_buffer;      /* For handling catastropic errors */};enum jstate {    JPEG_HEADER,                          /* Reading JFIF headers */    JPEG_START_DECOMPRESS,    JPEG_DECOMPRESS_PROGRESSIVE,          /* Output progressive pixels */    JPEG_DECOMPRESS_SEQUENTIAL,           /* Output sequential pixels */    JPEG_DONE,    JPEG_SINK_NON_JPEG_TRAILER,          /* Some image files have a */                                         /* non-JPEG trailer */    JPEG_ERROR    };void init_source(j_decompress_ptr jd);boolean fill_input_buffer(j_decompress_ptr jd);void skip_input_data(j_decompress_ptr jd, long num_bytes);void term_source(j_decompress_ptr jd);void error_exit(j_common_ptr cinfo);/* *  Implementation of a JPEG src object that understands our state machine */struct decoder_source_mgr {  /* public fields; must be first in this struct! */  struct jpeg_source_mgr pub;  JPEGImageReader *decoder;};class JPEGImageReader{public:    JPEGImageReader(JPEGImageDecoder* decoder)        : m_decoder(decoder)        , m_bufferLength(0)        , m_bytesToSkip(0)        , m_state(JPEG_HEADER)        , m_samples(0)    {        memset(&m_info, 0, sizeof(jpeg_decompress_struct));         /* We set up the normal JPEG error routines, then override error_exit. */        m_info.err = jpeg_std_error(&m_err.pub);        m_err.pub.error_exit = error_exit;        /* Allocate and initialize JPEG decompression object */        jpeg_create_decompress(&m_info);          decoder_source_mgr* src = NULL;        if (!m_info.src) {            src = (decoder_source_mgr*)fastCalloc(sizeof(decoder_source_mgr), 1);            if (!src) {                m_state = JPEG_ERROR;                return;            }        }        m_info.src = (jpeg_source_mgr*)src;        /* Set up callback functions. */        src->pub.init_source = init_source;        src->pub.fill_input_buffer = fill_input_buffer;        src->pub.skip_input_data = skip_input_data;        src->pub.resync_to_restart = jpeg_resync_to_restart;        src->pub.term_source = term_source;        src->decoder = this;    }    ~JPEGImageReader()    {        close();    }    void close() {        decoder_source_mgr* src = (decoder_source_mgr*)m_info.src;        if (src)            fastFree(src);        m_info.src = 0;        jpeg_destroy_decompress(&m_info);    }    void skipBytes(long num_bytes) {        decoder_source_mgr* src = (decoder_source_mgr*)m_info.src;        long bytesToSkip = std::min(num_bytes, (long)src->pub.bytes_in_buffer);        src->pub.bytes_in_buffer -= (size_t)bytesToSkip;        src->pub.next_input_byte += bytesToSkip;            if (num_bytes > bytesToSkip)            m_bytesToSkip = (size_t)(num_bytes - bytesToSkip);        else            m_bytesToSkip = 0;    }    bool decode(const Vector<char>& data, bool sizeOnly) {        m_decodingSizeOnly = sizeOnly;                unsigned newByteCount = data.size() - m_bufferLength;        unsigned readOffset = m_bufferLength - m_info.src->bytes_in_buffer;        m_info.src->bytes_in_buffer += newByteCount;        m_info.src->next_input_byte = (JOCTET*)(data.data()) + readOffset;                // If we still have bytes to skip, try to skip those now.        if (m_bytesToSkip)            skipBytes(m_bytesToSkip);        m_bufferLength = data.size();                // We need to do the setjmp here. Otherwise bad things will happen        if (setjmp(m_err.setjmp_buffer)) {            m_state = JPEG_SINK_NON_JPEG_TRAILER;            close();            return false;        }        switch (m_state) {            case JPEG_HEADER:            {                /* Read file parameters with jpeg_read_header() */                if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED)                    return true; /* I/O suspension */                /* let libjpeg take care of gray->RGB and YCbCr->RGB conversions */                switch (m_info.jpeg_color_space) {                    case JCS_GRAYSCALE:                    case JCS_RGB:                    case JCS_YCbCr:                        m_info.out_color_space = JCS_RGB;                        break;                    case JCS_CMYK:                    case JCS_YCCK:                    default:                        m_state = JPEG_ERROR;                        return false;                }                /*                 * Don't allocate a giant and superfluous memory buffer                 * when the image is a sequential JPEG.                 */                m_info.buffered_image = jpeg_has_multiple_scans(&m_info);                /* Used to set up image size so arrays can be allocated */                jpeg_calc_output_dimensions(&m_info);                /*                 * Make a one-row-high sample array that will go away                 * when done with image. Always make it big enough to                 * hold an RGB row.  Since this uses the IJG memory                 * manager, it must be allocated before the call to                 * jpeg_start_compress().                 */                int row_stride = m_info.output_width * 4; // RGBA buffer                m_samples = (*m_info.mem->alloc_sarray)((j_common_ptr) &m_info,                                           JPOOL_IMAGE,                                           row_stride, 1);                m_state = JPEG_START_DECOMPRESS;                // We can fill in the size now that the header is available.                if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) {                    m_state = JPEG_ERROR;                    return false;                }                if (m_decodingSizeOnly) {                    // We can stop here.                    // Reduce our buffer length and available data.                    m_bufferLength -= m_info.src->bytes_in_buffer;                    m_info.src->bytes_in_buffer = 0;                    return true;                }            }            case JPEG_START_DECOMPRESS:            {                /* Set parameters for decompression */                /* FIXME -- Should reset dct_method and dither mode                 * for final pass of progressive JPEG                 */                m_info.dct_method =  JDCT_ISLOW;                m_info.dither_mode = JDITHER_FS;                m_info.do_fancy_upsampling = true;                m_info.enable_2pass_quant = false;                m_info.do_block_smoothing = true;                /* Start decompressor */                if (!jpeg_start_decompress(&m_info))                    return true; /* I/O suspension */                /* If this is a progressive JPEG ... */                m_state = (m_info.buffered_image) ? JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL;            }                case JPEG_DECOMPRESS_SEQUENTIAL:            {                if (m_state == JPEG_DECOMPRESS_SEQUENTIAL) {                          if (!m_decoder->outputScanlines())                        return true; /* I/O suspension */      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -