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