summaryrefslogtreecommitdiffstats
path: root/kimgio
diff options
context:
space:
mode:
authorAlex Kent Hajnal <software@alephnull.net>2024-05-17 18:16:23 -0400
committerSlávek Banko <slavek.banko@axis.cz>2024-05-21 19:17:18 +0200
commit8414af176d732dfb8a2f93809f4361295bbfbdcb (patch)
tree1f0d1181b66195dfdc2c20b07663184eb7c0dd0c /kimgio
parentb74ce5928ca980e5b5a1e611404b32c22b174934 (diff)
downloadtdelibs-8414af176d732dfb8a2f93809f4361295bbfbdcb.tar.gz
tdelibs-8414af176d732dfb8a2f93809f4361295bbfbdcb.zip
Adds WebP read support to kimgio
Signed-off-by: Alex Kent Hajnal <software@alephnull.net> (cherry picked from commit 347a546d9dfb3210bcf907c3c622d6843d2ae9ce)
Diffstat (limited to 'kimgio')
-rw-r--r--kimgio/CMakeLists.txt13
-rw-r--r--kimgio/webp.cpp148
-rw-r--r--kimgio/webp.h17
-rw-r--r--kimgio/webp.kimgio85
4 files changed, 263 insertions, 0 deletions
diff --git a/kimgio/CMakeLists.txt b/kimgio/CMakeLists.txt
index be10cf809..325f136f1 100644
--- a/kimgio/CMakeLists.txt
+++ b/kimgio/CMakeLists.txt
@@ -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
diff --git a/kimgio/webp.cpp b/kimgio/webp.cpp
new file mode 100644
index 000000000..ea50ee3b6
--- /dev/null
+++ b/kimgio/webp.cpp
@@ -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
diff --git a/kimgio/webp.h b/kimgio/webp.h
new file mode 100644
index 000000000..6fc576c98
--- /dev/null
+++ b/kimgio/webp.h
@@ -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
+
diff --git a/kimgio/webp.kimgio b/kimgio/webp.kimgio
new file mode 100644
index 000000000..90bba6248
--- /dev/null
+++ b/kimgio/webp.kimgio
@@ -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