File indexing completed on 2025-01-26 04:10:56
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Adrian Page <adrian@pagenet.plus.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_jpeg_source.h" 0008 0009 #include <jerror.h> 0010 0011 #include <QIODevice> 0012 0013 #include "kis_debug.h" 0014 0015 namespace 0016 { 0017 0018 const qint64 INPUT_BUFFER_SIZE = 4096; 0019 0020 struct KisJPEGSourceManager : public jpeg_source_mgr 0021 { 0022 QIODevice* input; 0023 JOCTET* buffer; 0024 bool anyDataReceived; 0025 }; 0026 0027 typedef KisJPEGSourceManager* KisJPEGSourceManagerPtr; 0028 0029 extern "C" 0030 { 0031 0032 void init_source(j_decompress_ptr cinfo) 0033 { 0034 KisJPEGSourceManagerPtr src = (KisJPEGSourceManagerPtr)cinfo->src; 0035 src->anyDataReceived = false; 0036 } 0037 0038 boolean fill_input_buffer(j_decompress_ptr cinfo) 0039 { 0040 KisJPEGSourceManagerPtr src = (KisJPEGSourceManagerPtr)cinfo->src; 0041 qint64 numBytesRead = src->input->read(reinterpret_cast<char*>(src->buffer), INPUT_BUFFER_SIZE); 0042 0043 if (numBytesRead <= 0) { 0044 if (!src->anyDataReceived) { 0045 /* Treat empty input file as fatal error */ 0046 ERREXIT(cinfo, JERR_INPUT_EMPTY); 0047 } 0048 WARNMS(cinfo, JWRN_JPEG_EOF); 0049 0050 /* Insert a fake EOI marker */ 0051 src->buffer[0] = (JOCTET)0xFF; 0052 src->buffer[1] = (JOCTET)JPEG_EOI; 0053 numBytesRead = 2; 0054 } 0055 0056 src->next_input_byte = src->buffer; 0057 src->bytes_in_buffer = numBytesRead; 0058 src->anyDataReceived = true; 0059 0060 return (boolean)true; 0061 } 0062 0063 void skip_input_data(j_decompress_ptr cinfo, long numBytes) 0064 { 0065 KisJPEGSourceManagerPtr src = (KisJPEGSourceManagerPtr)cinfo->src; 0066 0067 if (numBytes > 0) { 0068 while (numBytes > (long)src->bytes_in_buffer) { 0069 numBytes -= (long)src->bytes_in_buffer; 0070 (void)fill_input_buffer(cinfo); 0071 } 0072 src->next_input_byte += (size_t)numBytes; 0073 src->bytes_in_buffer -= (size_t)numBytes; 0074 } 0075 } 0076 0077 void term_source(j_decompress_ptr cinfo) 0078 { 0079 Q_UNUSED(cinfo); 0080 } 0081 0082 } 0083 } 0084 0085 namespace KisJPEGSource 0086 { 0087 0088 void setSource(j_decompress_ptr cinfo, QIODevice* inputDevice) 0089 { 0090 KisJPEGSourceManagerPtr src = 0; 0091 0092 if (cinfo->src == 0) { 0093 cinfo->src = (struct jpeg_source_mgr*) 0094 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, 0095 sizeof(KisJPEGSourceManager)); 0096 src = (KisJPEGSourceManagerPtr)cinfo->src; 0097 src->buffer = (JOCTET*) 0098 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, 0099 INPUT_BUFFER_SIZE*sizeof(JOCTET)); 0100 } 0101 0102 src = (KisJPEGSourceManagerPtr)cinfo->src; 0103 src->init_source = init_source; 0104 src->fill_input_buffer = fill_input_buffer; 0105 src->skip_input_data = skip_input_data; 0106 src->resync_to_restart = jpeg_resync_to_restart; 0107 src->term_source = term_source; 0108 src->input = inputDevice; 0109 src->bytes_in_buffer = 0; 0110 src->next_input_byte = 0; 0111 } 0112 0113 } 0114