File indexing completed on 2025-02-02 04:21:39

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_destination.h"
0008 
0009 #include <jerror.h>
0010 
0011 #include <QIODevice>
0012 
0013 #include "kis_debug.h"
0014 
0015 namespace
0016 {
0017 
0018 const qint64 OUTPUT_BUFFER_SIZE = 4096;
0019 
0020 struct KisJPEGDestinationManager : public jpeg_destination_mgr
0021 {
0022     void writeData(j_compress_ptr cinfo, const qint64 numBytesToWrite)
0023     {
0024         if (output->write(reinterpret_cast<const char*>(buffer), numBytesToWrite) != numBytesToWrite) {
0025             ERREXIT(cinfo, JERR_FILE_WRITE);
0026         }
0027     }
0028 
0029     QIODevice* output;
0030     JOCTET* buffer;
0031 };
0032 
0033 typedef KisJPEGDestinationManager* KisJPEGDestinationManagerPtr;
0034 
0035 extern "C"
0036 {
0037 
0038 void init_destination(j_compress_ptr cinfo)
0039 {
0040     KisJPEGDestinationManagerPtr dest = (KisJPEGDestinationManagerPtr)cinfo->dest;
0041 
0042     dest->buffer = (JOCTET *)
0043       (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
0044                   OUTPUT_BUFFER_SIZE*sizeof(JOCTET));
0045 
0046     dest->next_output_byte = dest->buffer;
0047     dest->free_in_buffer = OUTPUT_BUFFER_SIZE;
0048 }
0049 
0050 boolean empty_output_buffer(j_compress_ptr cinfo)
0051 {
0052     KisJPEGDestinationManagerPtr dest = (KisJPEGDestinationManagerPtr)cinfo->dest;
0053 
0054     dest->writeData(cinfo, OUTPUT_BUFFER_SIZE);
0055     dest->next_output_byte = dest->buffer;
0056     dest->free_in_buffer = OUTPUT_BUFFER_SIZE;
0057 
0058     return (boolean)true;
0059 }
0060 
0061 void term_destination(j_compress_ptr cinfo)
0062 {
0063     KisJPEGDestinationManagerPtr dest = (KisJPEGDestinationManagerPtr)cinfo->dest;
0064     const qint64 numBytesToWrite = OUTPUT_BUFFER_SIZE-(qint64)dest->free_in_buffer;
0065 
0066     if (numBytesToWrite > 0) {
0067         dest->writeData(cinfo, numBytesToWrite);
0068     }
0069 }
0070 
0071 }
0072 }
0073 
0074 namespace KisJPEGDestination
0075 {
0076 
0077 void setDestination(j_compress_ptr cinfo, QIODevice* destinationDevice)
0078 {
0079     if (cinfo->dest == 0) {
0080         cinfo->dest = (struct jpeg_destination_mgr *)
0081             (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
0082                                         sizeof(KisJPEGDestinationManager));
0083     }
0084 
0085     KisJPEGDestinationManagerPtr dest = (KisJPEGDestinationManagerPtr)cinfo->dest;
0086 
0087     dest->init_destination = init_destination;
0088     dest->empty_output_buffer = empty_output_buffer;
0089     dest->term_destination = term_destination;
0090     dest->output = destinationDevice;
0091 }
0092 
0093 }
0094