Как при помощи JepgLib прочитать картинку из буффера в памяти, а не из файла?
Здравствуйте, Бабошин Андрей, Вы писали:
БА>jpeg_mem_src
чето ненаходится такой функции.
уменя либа:
/*
* jversion.h
*
* Copyright (C) 1991-2009, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
*/
#define JVERSION "7 27-Jun-2009"
#define JCOPYRIGHT "Copyright (C) 2009, Thomas G. Lane, Guido Vollbeding"
Здравствуйте, Nik_1, Вы писали:
N_>Как при помощи JepgLib прочитать картинку из буффера в памяти, а не из файла?
Можно еще посмотреть
stb_image.c
Здравствуйте, Nik_1, Вы писали:
N_>Как при помощи JepgLib прочитать картинку из буффера в памяти, а не из файла?
В принципе, если внимательно посмотреть на libjpeg, то там можно найти такую вот штуку:
jpeg_source_mgr
Эту структуру можно переопределить:
struct jpg_stream_source_mgr
{
struct jpeg_source_mgr pub;
IOStream *stream;
JOCTET *buffer;
bool firstTime;
};
static void ioInputStreamInit( j_decompress_ptr cinfo )
{
jpg_stream_source_mgr *src =
reinterpret_cast< jpg_stream_source_mgr* >( cinfo->src );
src->firstTime = true;
}
static boolean ioInputStreamFillBuffer( j_decompress_ptr cinfo )
{
jpg_stream_source_mgr *src =
reinterpret_cast< jpg_stream_source_mgr* >( cinfo->src );
int remainData = src->stream->remainDataSize();
int readedData = 0;
if( remainData <= 0 )
{
if( src->firstTime ) // Treat empty input file as fatal error
ERREXIT( cinfo, JERR_INPUT_EMPTY );
WARNMS( cinfo, JWRN_JPEG_EOF );
// Insert a fake EOI marker
src->buffer[0] = static_cast< JOCTET >( 0xFF );
src->buffer[1] = static_cast< JOCTET >( JPEG_EOI );
readedData = 2;
}
else
{
readedData = ( remainData > JPG_BUFFER_SIZE ) ?
( JPG_BUFFER_SIZE ) :
( remainData );
if( !src->stream->readData( src->buffer, readedData ) )
ERREXIT( cinfo, JERR_FILE_READ );
}
src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer = readedData;
src->firstTime = false;
return TRUE;
}
static void ioInputStreamSkipData( j_decompress_ptr cinfo, long countBytes )
{
struct jpeg_source_mgr *src = cinfo->src;
if( countBytes > 0 )
{
while( countBytes > src->bytes_in_buffer )
{
countBytes -= src->bytes_in_buffer;
ioInputStreamFillBuffer( cinfo );
}
src->next_input_byte += countBytes;
src->bytes_in_buffer -= countBytes;
}
}
static void ioInputStreamClose( j_decompress_ptr cinfo )
{
}
void attachInputStreamToJPG( j_decompress_ptr cinfo, IOStream &stream )
{
jpg_stream_source_mgr *src;
if( cinfo->src == 0 )
{
cinfo->src = reinterpret_cast< struct jpeg_source_mgr* >(
( *cinfo->mem->alloc_small )(
reinterpret_cast< j_common_ptr >( cinfo ),
JPOOL_PERMANENT,
sizeof( jpg_stream_source_mgr ) ) );
src = reinterpret_cast< jpg_stream_source_mgr* >( cinfo->src );
src->buffer = reinterpret_cast< JOCTET* >(
( *cinfo->mem->alloc_small )(
reinterpret_cast< j_common_ptr >( cinfo ),
JPOOL_PERMANENT,
JPG_BUFFER_SIZE ) );
}
src = reinterpret_cast< jpg_stream_source_mgr* >( cinfo->src );
src->pub.init_source = ioInputStreamInit;
src->pub.fill_input_buffer = ioInputStreamFillBuffer;
src->pub.skip_input_data = ioInputStreamSkipData;
src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.term_source = ioInputStreamClose;
src->stream = &stream;
src->pub.bytes_in_buffer = 0;
src->pub.next_input_byte = 0;
}
IOStream в данном случае у меня определен так:
class IOStream
{
public:
virtual bool isValid() const = 0;
virtual bool readData( void *data, int size ) = 0;
virtual bool writeData( const void *data, int size ) = 0;
virtual bool flush() = 0;
virtual int position() const = 0;
virtual bool setPosition( int newPosition ) = 0;
virtual int remainDataSize() const = 0;
virtual bool isEos() const = 0;
virtual int size() const = 0;
IOStream() {};
virtual ~IOStream() {};
private:
IOStream( const IOStream& );
IOStream &operator = ( const IOStream& );
};
Естественно избыточно и не совсем правильно, но я изначально не рассчитывал на этот IOStream. Оно у меня как-то спонтанно и бездумно родилось
Потом это к jpeg_decompress_struct цепляется так:
struct jpeg_decompress_struct cinfo;
IOSomeSuperStream stream( ... );
jpeg_create_decompress( &cinfo );
attachInputStreamToJPG( &cinfo, stream );
jpeg_read_header( &cinfo, TRUE );
...
На запись так же можно прицепить всю эту красоту.
Тогда можно вообще откуда угодно читать-писать с помощью libjpeg. Единственное только, что для чтения из памяти там и правда уже есть встроенный source manager.
Черт
Забыл про это:
static const int JPG_BUFFER_SIZE = 4096;
Оно определяется самим мэнеджером.