Adds WebP read support to kimgio

Signed-off-by: Alex Kent Hajnal <software@alephnull.net>
pull/277/head
Alex Kent Hajnal 1 month ago committed by Slávek Banko
parent 7d228ae9aa
commit 347a546d9d

@ -106,6 +106,7 @@ option( WITH_IMAGETOPS_BINARY "Enable installation of imagetops binary" ${WITH_A
option( WITH_LUA "Enable LUA support" ${WITH_ALL_OPTIONS} )
option( WITH_TIFF "Enable tiff support" ${WITH_ALL_OPTIONS} )
option( WITH_JASPER "Enable jasper (jpeg2k) support" ${WITH_ALL_OPTIONS} )
option( WITH_WEBP "Enable WebP support" ${WITH_ALL_OPTIONS} )
option( WITH_OPENEXR "Enable openexr support" ${WITH_ALL_OPTIONS} )
option( WITH_UTEMPTER "Use utempter for utmp management" ${WITH_ALL_OPTIONS} )
option( WITH_AVAHI "Enable AVAHI support" ${WITH_ALL_OPTIONS} )
@ -891,6 +892,32 @@ if( WITH_JASPER )
endif( WITH_JASPER )
##### check for webp ############################
if( WITH_WEBP )
pkg_search_module( WEBP libwebp )
if( WEBP_FOUND )
set( HAVE_WEBP 1 )
else ( NOT WEBP_FOUND )
check_include_file( "webp/decode.h" HAVE_WEBP_DECODE_H)
if ( HAVE_WEBP_DECODE_H )
check_library_exists( webp WebPGetInfo "" HAVE_WEBP__WEBPGETINFO )
check_library_exists( webp WebPDecodeARGBInto "" HAVE_WEBP__WEBPDECODEARGBINTO )
check_library_exists( webp WebPDecodeBGRAInto "" HAVE_WEBP__WEBPDECODEBGRAINTO )
if( HAVE_WEBP__WEBPGETINFO AND HAVE_WEBP__WEBPDECODEARGBINTO AND HAVE_WEBP__WEBPDECODEBGRAINTO )
set( HAVE_WEBP 1 )
endif( )
endif( HAVE_WEBP_DECODE_H )
endif( WEBP_FOUND )
if ( HAVE_WEBP )
set( WEBP_LIBRARIES webp )
message( STATUS "WebP support enabled" )
else ( NOT HAVE_WEBP )
tde_message_fatal( "WebP support requested, but not found on your system" )
endif( HAVE_WEBP)
endif( WITH_WEBP )
##### check for openexr #########################
if( WITH_OPENEXR )

@ -167,6 +167,19 @@ tde_add_kpart( ${target}
)
##### kimg_webp #################################
if( HAVE_WEBP )
set( target kimg_webp )
tde_add_kpart( ${target}
SOURCES webp.cpp
LINK tdecore-shared ${WEBP_LIBRARIES}
DESTINATION ${PLUGIN_INSTALL_DIR}
)
install( FILES webp.kimgio DESTINATION ${SERVICES_INSTALL_DIR} )
endif( HAVE_WEBP )
##### other data ################################
install( FILES

@ -0,0 +1,148 @@
// WebP read support
// © 2024 Alexander Hajnal
// Based loosely on jp2.cpp
//
// If implementing write support it's suggested to use lossless mode with exact
// mode enabled when the quality setting is 100 and for other qualities to use
// lossy mode with the default settings.
//
// This library is distributed under the conditions of the GNU LGPL.
#include "config.h"
#include <tdetempfile.h>
#include <tqfile.h>
#include <tqimage.h>
#include <webp/decode.h>
#include <cstdlib>
#ifdef __cplusplus
extern "C" {
#endif
TDE_EXPORT void kimgio_webp_read( TQImageIO* io )
{
int width, height;
FILE* in;
// === Read the source file ===
// Based on code in jp2.cpp
// for QIODevice's other than TQFile, a temp. file is used.
KTempFile* tempf = 0;
TQFile* qf = 0;
if( ( qf = dynamic_cast<TQFile*>( io->ioDevice() ) ) ) {
// great, it's a TQFile. Let's just take the filename.
in = fopen( TQFile::encodeName( qf->name() ), "rb" );
} else {
// not a TQFile. Copy the whole data to a temp. file.
tempf = new KTempFile();
if( tempf->status() != 0 ) {
delete tempf;
return;
} // if
tempf->setAutoDelete( true );
TQFile* out = tempf->file();
// 4096 (=4k) is a common page size.
TQByteArray b( 4096 );
TQ_LONG size;
// 0 or -1 is EOF / error
while( ( size = io->ioDevice()->readBlock( b.data(), 4096 ) ) > 0 ) {
// in case of a write error, still give the decoder a try
if( ( out->writeBlock( b.data(), size ) ) == -1 ) break;
} // while
// flush everything out to disk
out->flush();
in = fopen( TQFile::encodeName( tempf->name() ), "rb" );
} // else
if( ! in ) {
delete tempf;
return;
} // if
// File is now open
// === Load compressed data ===
// Find file's size
fseek(in, 0L, SEEK_END); // Seek to end of file
long size = ftell(in); // Get position (i.e. the file size)
fseek(in, 0L, SEEK_SET); // Seek back to start of file
// Sanity check
if ( size > SIZE_MAX ) {
// File size is larger than a size_t can hold
fclose( in );
delete tempf;
return;
}
// Allocate a buffer for the compressed data
uint8_t* compressed_image = (uint8_t*)malloc(size);
if( ! compressed_image ) {
// malloc failed
fclose( in );
delete tempf;
return;
} // if
// Read compressed image into buffer
size_t bytes_read = fread( compressed_image, sizeof(uint8_t), size, in );
// Close the compressed image file
fclose( in );
delete tempf;
if ( bytes_read < size ) {
// Read failed
free( compressed_image );
return;
}
// === Decompress image ===
// Get image dimensions
if ( ! WebPGetInfo( compressed_image, size, &width, &height ) ) {
// Error
free( compressed_image );
return;
}
// Create an appropriately sized image
TQImage image;
if( ! image.create( width, height, 32 ) ) {
// Error
free( compressed_image );
return;
}
// Enable alpha channel
image.setAlphaBuffer(true);
// Get the image buffer
uint32_t* data = (uint32_t*)image.bits();
// Decompress the image
#ifdef WORDS_BIGENDIAN
if ( ! WebPDecodeARGBInto( compressed_image, size, (uint8_t*)data, width*height*4, width*4) ) {
#else
if ( ! WebPDecodeBGRAInto( compressed_image, size, (uint8_t*)data, width*height*4, width*4) ) {
#endif
// Error
free( compressed_image );
return;
}
// Free the compressed image buffer
free( compressed_image );
// Finalize load
io->setImage( image );
io->setStatus( 0 );
} // kimgio_webp_read
#ifdef __cplusplus
}
#endif

@ -0,0 +1,17 @@
// WebP read support
// © 2024 Alexander Hajnal
// Based on jp2.h
//
// This library is distributed under the conditions of the GNU LGPL.
#ifndef KIMG_WEBP_H
#define KIMG_WEBP_H
class TQImageIO;
extern "C" {
void kimgio_webp_read( TQImageIO* io );
// void kimgio_webp_write( TQImageIO* io ); // Not currently supported
} // extern "C"
#endif

@ -0,0 +1,85 @@
[Image Format]
Type=webp
Header=^RIFF[\x00-\xFF]{4}WEBP
Name=WebP Image
Name[af]=WebP Beeld
Name[ar]=صورة من نوع WebP
Name[az]=WebP Rəsmi
Name[be]=Малюнак WebP
Name[bg]=WebP изображение
Name[bn]=WebP চিত্র
Name[br]=Skeudenn WebP
Name[bs]=WebP slika
Name[ca]=Imatge WebP
Name[cs]=Obrázek ve formátu WebP
Name[csb]=Òbrôzk WebP
Name[cy]=Delwedd WebP
Name[da]=WebP-billede
Name[de]=WebP-Bild
Name[el]=Εικόνα WebP
Name[eo]=WebP bildo
Name[es]=Imagen WebP
Name[et]=WebP pildifail
Name[eu]=WebP irudia
Name[fa]=تصویر WebP
Name[fi]=WebP -kuva
Name[fr]=Image WebP
Name[fy]=WebP ôfbylding
Name[ga]=Íomhá WebP
Name[gl]=Imaxe WebP
Name[he]=תמונת WebP
Name[hi]=WebP छवि
Name[hr]=WebP slika
Name[hu]=WebP-kép
Name[id]=Gambar WebP
Name[is]=WebP mynd
Name[it]=Immagine WebP
Name[ja]=WebP 画像
Name[ka]=WebP ნახატი
Name[kk]=WebP кескіні
Name[km]=រូបភាព WebP
Name[ko]=WebP 그림
Name[lb]=WebP-Bild
Name[lt]=WebP paveiksliukas
Name[lv]=WebP attēls
Name[mk]=WebP слика
Name[mn]=WebP Зураг
Name[ms]=Imej WebP
Name[nb]=WebP bilde
Name[nds]=WebP-Bild
Name[ne]=WebP छवि
Name[nl]=WebP-afbeelding
Name[nn]=WebP-bilete
Name[pa]=WebP ਚਿੱਤਰ
Name[pl]=Obrazek WebP
Name[pt]=Imagem WebP
Name[pt_BR]=Imagem WebP
Name[ro]=Imagine WebP
Name[ru]=Рисунок WebP
Name[rw]=WebP Ishusho
Name[se]=WebP-govva
Name[sk]=WebP obrázok
Name[sl]=Slika WebP
Name[sq]=Imazh WebP
Name[sr]=WebP слика
Name[sr@Latn]=WebP slika
Name[sv]=WebP-bild
Name[ta]=WebP பிம்பம்
Name[te]=WebP ప్రతిబింబం
Name[tg]=Тасвири WebP
Name[th]=แฟ้มภาพ WebP
Name[tr]=WebP Resim Dosyası
Name[tt]=WebP Süräte
Name[uk]=Зображення WebP
Name[uz]=WebP-rasm
Name[uz@cyrillic]=WebP-расм
Name[vi]=Ảnh WebP
Name[wa]=Imådje WebP
Name[zh_CN]=WebP 图像
Name[zh_HK]=WebP 圖檔
Name[zh_TW]=WebP 影像
Read=true
Write=false
Suffices=webp,WEBP
Mimetype=image/webp
Library=kimg_webp.la
Loading…
Cancel
Save