Skip to content

Commit b4cd473

Browse files
committed
Added convenience function to Rawtile class to duplicate bands for encoders that cannot natively handle single band monochrome images: simplifies WebP encoding
1 parent 917fe71 commit b4cd473

File tree

3 files changed

+51
-21
lines changed

3 files changed

+51
-21
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
05/09/2024:
2+
- Added convenience function to Rawtile class to duplicate bands for encoders that cannot natively handle
3+
single band monochrome images: simplifies WebP encoding.
4+
5+
16
29/06/2024:
27
- Updated autoconf tiff m4 to search for tiffio.h rather than just tiff.h when using TIFFOpen().
38
- Switched metadata assignment within input image classes to use more efficient map insert() syntax.

src/RawTile.h

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/* IIPImage Server
44
5-
Copyright (C) 2000-2023 Ruven Pillay.
5+
Copyright (C) 2000-2024 Ruven Pillay.
66
77
This program is free software; you can redistribute it and/or modify
88
it under the terms of the GNU General Public License as published by
@@ -271,7 +271,7 @@ class RawTile {
271271
unsigned char* src_ptr = (unsigned char*) buffer;
272272
unsigned char* dst_ptr = (unsigned char*) data;
273273

274-
// Copy one scanline at a time
274+
// Copy one entire scanline at a time
275275
unsigned int dlen = w * channels * (bpc/8);
276276
unsigned int slen = width * channels * (bpc/8);
277277

@@ -293,6 +293,44 @@ class RawTile {
293293

294294

295295

296+
/// Expand monochrome 1 band image to 3 by duplicating channels
297+
void triplicate() {
298+
299+
if( channels != 1 ) return;
300+
301+
// Keep track of original data buffer and whether we manage it
302+
void* buffer = data;
303+
int mm = memoryManaged;
304+
305+
// Create a new buffer with the new size - make sure we update channel number first
306+
channels = 3;
307+
allocate();
308+
309+
// Loop through each pixel and duplicate
310+
unsigned int len = width * height;
311+
uint32_t n = 0;
312+
for( uint32_t i=0; i<len; i++ ){
313+
for( uint8_t k=0; k<3; k++ ){
314+
if( bpc == 32 ){
315+
if( sampleType == SampleType::FLOATINGPOINT ) ((float*) data)[n+k] = ((float*) buffer)[i];
316+
else ((unsigned int*) data)[n+k] = ((unsigned int*) buffer)[i];
317+
}
318+
else if( bpc == 16 ) ((unsigned short*) data)[n+k] = ((unsigned short*) buffer)[i];
319+
else ((unsigned char*) data)[n+k] = ((unsigned char*) buffer)[i];
320+
}
321+
n += 3;
322+
}
323+
324+
// Delete original memory buffer
325+
if( mm ) deallocate( buffer );
326+
327+
// Set the new tile dimensions and data storage size
328+
capacity = len; // Need to set this manually as deallocate sets this to zero
329+
dataLength = len;
330+
};
331+
332+
333+
296334
/// Overloaded equality operator
297335
friend int operator == ( const RawTile& A, const RawTile& B ) {
298336
if( (A.tileNum == B.tileNum) &&

src/WebPCompressor.cc

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void WebPCompressor::InitCompression( const RawTile& rawtile, unsigned int strip
3333
tile.width = rawtile.width;
3434
tile.height = rawtile.height;
3535
tile.channels = rawtile.channels;
36+
tile.bpc = rawtile.bpc;
3637
tile.data = rawtile.data;
3738
tile.dataLength = rawtile.dataLength;
3839
tile.memoryManaged = 0; // We don't want the RawTile destructor to free this memory
@@ -84,24 +85,11 @@ unsigned int WebPCompressor::Finish( unsigned char* output ){
8485
/// Compress a single tile of data
8586
unsigned int WebPCompressor::Compress( RawTile& rawtile ){
8687

87-
// Import data from our RawTile structure
88-
unsigned char* tmp = NULL;
89-
const uint8_t* rgb = (uint8_t*) rawtile.data;
90-
9188
// WebP cannot handle greyscale, so duplicate our data to 3 bands
92-
if( rawtile.channels == 1 ){
93-
unsigned int len = rawtile.width*rawtile.height;
94-
tmp = new unsigned char[len*3];
95-
unsigned int n = 0;
96-
for( unsigned int i=0; i<len; i++ ){
97-
tmp[n++] = rgb[i];
98-
tmp[n++] = rgb[i];
99-
tmp[n++] = rgb[i];
100-
}
101-
rgb = (uint8_t*) tmp;
102-
rawtile.channels = 3;
103-
}
89+
if( rawtile.channels == 1 ) rawtile.triplicate();
10490

91+
// Import data from our RawTile structure
92+
const uint8_t* rgb = (uint8_t*) rawtile.data;
10593

10694
// Create WebP input data structure
10795
WebPPicture pic;
@@ -129,9 +117,7 @@ unsigned int WebPCompressor::Compress( RawTile& rawtile ){
129117
}
130118
}
131119

132-
// Delete any temporary buffer
133-
if( tmp ) delete[] tmp;
134-
120+
135121
// Encode our image buffer
136122
WebPEncode( &config, &pic );
137123

@@ -173,6 +159,7 @@ unsigned int WebPCompressor::Compress( RawTile& rawtile ){
173159
rawtile.capacity = size;
174160
}
175161

162+
176163
// Copy our data back into our rawtile buffer
177164
memcpy( rawtile.data, buffer, size );
178165
rawtile.dataLength = size;

0 commit comments

Comments
 (0)