gfx/skia/trunk/src/images/SkJpegUtility.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/images/SkJpegUtility.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,170 @@
     1.4 +/*
     1.5 + * Copyright 2010 The Android Open Source Project
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +
    1.12 +#include "SkJpegUtility.h"
    1.13 +
    1.14 +/////////////////////////////////////////////////////////////////////
    1.15 +static void sk_init_source(j_decompress_ptr cinfo) {
    1.16 +    skjpeg_source_mgr*  src = (skjpeg_source_mgr*)cinfo->src;
    1.17 +    src->next_input_byte = (const JOCTET*)src->fBuffer;
    1.18 +    src->bytes_in_buffer = 0;
    1.19 +#ifdef SK_BUILD_FOR_ANDROID
    1.20 +    src->current_offset = 0;
    1.21 +#endif
    1.22 +    if (!src->fStream->rewind()) {
    1.23 +        SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
    1.24 +        cinfo->err->error_exit((j_common_ptr)cinfo);
    1.25 +    }
    1.26 +}
    1.27 +
    1.28 +#ifdef SK_BUILD_FOR_ANDROID
    1.29 +static boolean sk_seek_input_data(j_decompress_ptr cinfo, long byte_offset) {
    1.30 +    skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
    1.31 +    size_t bo = (size_t) byte_offset;
    1.32 +
    1.33 +    if (bo > src->current_offset) {
    1.34 +        (void)src->fStream->skip(bo - src->current_offset);
    1.35 +    } else {
    1.36 +        if (!src->fStream->rewind()) {
    1.37 +            SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
    1.38 +            cinfo->err->error_exit((j_common_ptr)cinfo);
    1.39 +            return false;
    1.40 +        }
    1.41 +        (void)src->fStream->skip(bo);
    1.42 +    }
    1.43 +
    1.44 +    src->current_offset = bo;
    1.45 +    src->next_input_byte = (const JOCTET*)src->fBuffer;
    1.46 +    src->bytes_in_buffer = 0;
    1.47 +    return true;
    1.48 +}
    1.49 +#endif
    1.50 +
    1.51 +static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) {
    1.52 +    skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
    1.53 +    if (src->fDecoder != NULL && src->fDecoder->shouldCancelDecode()) {
    1.54 +        return FALSE;
    1.55 +    }
    1.56 +    size_t bytes = src->fStream->read(src->fBuffer, skjpeg_source_mgr::kBufferSize);
    1.57 +    // note that JPEG is happy with less than the full read,
    1.58 +    // as long as the result is non-zero
    1.59 +    if (bytes == 0) {
    1.60 +        return FALSE;
    1.61 +    }
    1.62 +
    1.63 +#ifdef SK_BUILD_FOR_ANDROID
    1.64 +    src->current_offset += bytes;
    1.65 +#endif
    1.66 +    src->next_input_byte = (const JOCTET*)src->fBuffer;
    1.67 +    src->bytes_in_buffer = bytes;
    1.68 +    return TRUE;
    1.69 +}
    1.70 +
    1.71 +static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
    1.72 +    skjpeg_source_mgr*  src = (skjpeg_source_mgr*)cinfo->src;
    1.73 +
    1.74 +    if (num_bytes > (long)src->bytes_in_buffer) {
    1.75 +        size_t bytesToSkip = num_bytes - src->bytes_in_buffer;
    1.76 +        while (bytesToSkip > 0) {
    1.77 +            size_t bytes = src->fStream->skip(bytesToSkip);
    1.78 +            if (bytes <= 0 || bytes > bytesToSkip) {
    1.79 +//              SkDebugf("xxxxxxxxxxxxxx failure to skip request %d returned %d\n", bytesToSkip, bytes);
    1.80 +                cinfo->err->error_exit((j_common_ptr)cinfo);
    1.81 +                return;
    1.82 +            }
    1.83 +#ifdef SK_BUILD_FOR_ANDROID
    1.84 +            src->current_offset += bytes;
    1.85 +#endif
    1.86 +            bytesToSkip -= bytes;
    1.87 +        }
    1.88 +        src->next_input_byte = (const JOCTET*)src->fBuffer;
    1.89 +        src->bytes_in_buffer = 0;
    1.90 +    } else {
    1.91 +        src->next_input_byte += num_bytes;
    1.92 +        src->bytes_in_buffer -= num_bytes;
    1.93 +    }
    1.94 +}
    1.95 +
    1.96 +static void sk_term_source(j_decompress_ptr /*cinfo*/) {}
    1.97 +
    1.98 +
    1.99 +///////////////////////////////////////////////////////////////////////////////
   1.100 +
   1.101 +skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder)
   1.102 +    : fStream(SkRef(stream))
   1.103 +    , fDecoder(decoder) {
   1.104 +
   1.105 +    init_source = sk_init_source;
   1.106 +    fill_input_buffer = sk_fill_input_buffer;
   1.107 +    skip_input_data = sk_skip_input_data;
   1.108 +    resync_to_restart = jpeg_resync_to_restart;
   1.109 +    term_source = sk_term_source;
   1.110 +#ifdef SK_BUILD_FOR_ANDROID
   1.111 +    seek_input_data = sk_seek_input_data;
   1.112 +#endif
   1.113 +//    SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize);
   1.114 +}
   1.115 +
   1.116 +skjpeg_source_mgr::~skjpeg_source_mgr() {
   1.117 +    SkSafeUnref(fStream);
   1.118 +}
   1.119 +
   1.120 +///////////////////////////////////////////////////////////////////////////////
   1.121 +
   1.122 +static void sk_init_destination(j_compress_ptr cinfo) {
   1.123 +    skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest;
   1.124 +
   1.125 +    dest->next_output_byte = dest->fBuffer;
   1.126 +    dest->free_in_buffer = skjpeg_destination_mgr::kBufferSize;
   1.127 +}
   1.128 +
   1.129 +static boolean sk_empty_output_buffer(j_compress_ptr cinfo) {
   1.130 +    skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest;
   1.131 +
   1.132 +//  if (!dest->fStream->write(dest->fBuffer, skjpeg_destination_mgr::kBufferSize - dest->free_in_buffer))
   1.133 +    if (!dest->fStream->write(dest->fBuffer,
   1.134 +            skjpeg_destination_mgr::kBufferSize)) {
   1.135 +        ERREXIT(cinfo, JERR_FILE_WRITE);
   1.136 +        return false;
   1.137 +    }
   1.138 +
   1.139 +    dest->next_output_byte = dest->fBuffer;
   1.140 +    dest->free_in_buffer = skjpeg_destination_mgr::kBufferSize;
   1.141 +    return TRUE;
   1.142 +}
   1.143 +
   1.144 +static void sk_term_destination (j_compress_ptr cinfo) {
   1.145 +    skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest;
   1.146 +
   1.147 +    size_t size = skjpeg_destination_mgr::kBufferSize - dest->free_in_buffer;
   1.148 +    if (size > 0) {
   1.149 +        if (!dest->fStream->write(dest->fBuffer, size)) {
   1.150 +            ERREXIT(cinfo, JERR_FILE_WRITE);
   1.151 +            return;
   1.152 +        }
   1.153 +    }
   1.154 +    dest->fStream->flush();
   1.155 +}
   1.156 +
   1.157 +skjpeg_destination_mgr::skjpeg_destination_mgr(SkWStream* stream)
   1.158 +        : fStream(stream) {
   1.159 +    this->init_destination = sk_init_destination;
   1.160 +    this->empty_output_buffer = sk_empty_output_buffer;
   1.161 +    this->term_destination = sk_term_destination;
   1.162 +}
   1.163 +
   1.164 +void skjpeg_error_exit(j_common_ptr cinfo) {
   1.165 +    skjpeg_error_mgr* error = (skjpeg_error_mgr*)cinfo->err;
   1.166 +
   1.167 +    (*error->output_message) (cinfo);
   1.168 +
   1.169 +    /* Let the memory manager delete any temp files before we die */
   1.170 +    jpeg_destroy(cinfo);
   1.171 +
   1.172 +    longjmp(error->fJmpBuf, -1);
   1.173 +}

mercurial