1a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk/* 2a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Copyright (C) 2013 The Android Open Source Project 3a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * 4a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * you may not use this file except in compliance with the License. 6a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * You may obtain a copy of the License at 7a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * 8a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * 10a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Unless required by applicable law or agreed to in writing, software 11a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * See the License for the specific language governing permissions and 14a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * limitations under the License. 15a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk */ 16a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 17a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk#include "jpeg_hook.h" 18a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk#include "jpeg_writer.h" 19a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk#include "error_codes.h" 20a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 21a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk#include <setjmp.h> 22a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk#include <assert.h> 23a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 24a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben BrunkJpegWriter::JpegWriter() : mInfo(), 25a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mErrorManager(), 26a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBuf(NULL), 27a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineIter(NULL), 28a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBuflen(0), 29a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining(0), 30a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mFormat(), 31a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mFinished(false), 32a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mSetup(false) {} 33a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 34a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben BrunkJpegWriter::~JpegWriter() { 35a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (reset() != J_SUCCESS) { 36a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk LOGE("Failed to destroy compress object, may leak memory."); 37a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 38a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 39a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 40a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkconst int32_t JpegWriter::DEFAULT_X_DENSITY = 300; 41a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkconst int32_t JpegWriter::DEFAULT_Y_DENSITY = 300; 42a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkconst int32_t JpegWriter::DEFAULT_DENSITY_UNIT = 1; 43a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 44a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkint32_t JpegWriter::setup(JNIEnv *env, jobject out, int32_t width, int32_t height, 45a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk Jpeg_Config::Format format, int32_t quality) { 46a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (mFinished || mSetup) { 47a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 48a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 49a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (env->ExceptionCheck()) { 50a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_EXCEPTION; 51a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 52a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (height <= 0 || width <= 0 || quality <= 0 || quality > 100) { 53a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_BAD_ARGS; 54a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 55a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Setup error handler 56a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk SetupErrMgr(reinterpret_cast<j_common_ptr>(&mInfo), &mErrorManager); 57a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 58a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Set jump address for error handling 59a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (setjmp(mErrorManager.setjmp_buf)) { 60a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 61a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 62a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 63a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Setup cinfo struct 64a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_create_compress(&mInfo); 65a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 66a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Setup global java refs 67a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk int32_t flags = MakeDst(&mInfo, env, out); 68a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (flags != J_SUCCESS) { 69a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return flags; 70a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 71a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 72a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Initialize width, height, and color space 73a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.image_width = width; 74a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.image_height = height; 75a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk const int components = (static_cast<int>(format) & 0xff); 76a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk switch (components) { 77a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk case 1: 78a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.input_components = 1; 79a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.in_color_space = JCS_GRAYSCALE; 80a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk break; 81a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk case 3: 82a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk case 4: 83a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.input_components = 3; 84a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.in_color_space = JCS_RGB; 85a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk break; 86a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk default: 87a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_BAD_ARGS; 88a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 89a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 90a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Set defaults 91a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_set_defaults(&mInfo); 92a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.density_unit = DEFAULT_DENSITY_UNIT; // JFIF code for pixel size units: 93a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // 1 = in, 2 = cm 94a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.X_density = DEFAULT_X_DENSITY; // Horizontal pixel density 95a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mInfo.Y_density = DEFAULT_Y_DENSITY; // Vertical pixel density 96a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 97a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Set compress quality 98a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_set_quality(&mInfo, quality, TRUE); 99a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 100a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mFormat = format; 101a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 102a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Setup scanline buffer 103a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBuflen = width * components; 104a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining = mScanlineBuflen; 105a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBuf = (JSAMPLE *) (mInfo.mem->alloc_small)( 106a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk reinterpret_cast<j_common_ptr>(&mInfo), JPOOL_PERMANENT, 107a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBuflen * sizeof(JSAMPLE)); 108a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineIter = mScanlineBuf; 109a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 110a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Start compression 111a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_start_compress(&mInfo, TRUE); 112a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mSetup = true; 113a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_SUCCESS; 114a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 115a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 116a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkint32_t JpegWriter::write(int8_t* bytes, int32_t length) { 117a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (!mSetup) { 118a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 119a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 120a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (mFinished) { 121a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return 0; 122a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 123a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Set jump address for error handling 124a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (setjmp(mErrorManager.setjmp_buf)) { 125a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 126a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 127a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (length < 0 || bytes == NULL) { 128a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_BAD_ARGS; 129a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 130a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 131a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk int32_t total_length = length; 132a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk JSAMPROW row_pointer[1]; 133a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk while (mInfo.next_scanline < mInfo.image_height) { 134a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (length < mScanlineBytesRemaining) { 135a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // read partial scanline and return 136a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk memcpy((void*) mScanlineIter, (void*) bytes, 137a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk length * sizeof(int8_t)); 138a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining -= length; 139a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineIter += length; 140a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return total_length; 141a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } else if (length > 0) { 142a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // read full scanline 143a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk memcpy((void*) mScanlineIter, (void*) bytes, 144a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining * sizeof(int8_t)); 145a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk bytes += mScanlineBytesRemaining; 146a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk length -= mScanlineBytesRemaining; 147a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining = 0; 148a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 149a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Do in-place pixel formatting 150a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk formatPixels(static_cast<uint8_t*>(mScanlineBuf), mScanlineBuflen); 151a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk row_pointer[0] = mScanlineBuf; 152a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Do compression 153a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (jpeg_write_scanlines(&mInfo, row_pointer, 1) != 1) { 154a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 155a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 156a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Reset scanline buffer 157a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineBytesRemaining = mScanlineBuflen; 158a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mScanlineIter = mScanlineBuf; 159a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 160a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_finish_compress(&mInfo); 161a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mFinished = true; 162a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return total_length - length; 163a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 164a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 165a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk// Does in-place pixel formatting 166a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkvoid JpegWriter::formatPixels(uint8_t* buf, int32_t len) { 167a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Assumes len is a multiple of 4 for RGBA and ABGR pixels. 168a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk assert((len % 4) == 0); 169a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk uint8_t* d = buf; 170a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk switch (mFormat) { 171a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk case Jpeg_Config::FORMAT_RGBA: { 172a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Strips alphas 173a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk for (int i = 0; i < len / 4; ++i, buf += 4) { 174a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[0]; 175a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[1]; 176a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[2]; 177a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 178a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk break; 179a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 180a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk case Jpeg_Config::FORMAT_ABGR: { 181a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Strips alphas and flips endianness 182a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (len / 4 >= 1) { 183a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[3]; 184a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk uint8_t tmp = *d; 185a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[2]; 186a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = tmp; 187a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 188a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk for (int i = 1; i < len / 4; ++i, buf += 4) { 189a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[3]; 190a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[2]; 191a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *d++ = buf[1]; 192a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 193a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk break; 194a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 195a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk default: { 196a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Do nothing 197a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk break; 198a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 199a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 200a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 201a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 202a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkvoid JpegWriter::updateEnv(JNIEnv *env) { 203a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk UpdateDstEnv(&mInfo, env); 204a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 205a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk 206a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkint32_t JpegWriter::reset() { 207a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Set jump address for error handling 208a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk if (setjmp(mErrorManager.setjmp_buf)) { 209a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_ERROR_FATAL; 210a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk } 211a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Clean up global java references 212a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk CleanDst(&mInfo); 213a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk // Wipe compress struct, free memory pools 214a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk jpeg_destroy_compress(&mInfo); 215a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mFinished = false; 216a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk mSetup = false; 217a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk return J_SUCCESS; 218a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk} 219