Skip to content

Commit

Permalink
FEAT: QOI codec (The "Quite OK Image" format for fast, lossless image…
Browse files Browse the repository at this point in the history
… compression)

resolves: #39
  • Loading branch information
Oldes committed Dec 1, 2021
1 parent a09ee2f commit 15de62c
Show file tree
Hide file tree
Showing 6 changed files with 793 additions and 0 deletions.
5 changes: 5 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ Credits for Non-REBOL orginated C files and modules
* UTF-8 decoder:
Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>

* QOI codec (optional):
The "Quite OK Image" format for fast, lossless image compression
Copyright (c) 2021, Dominic Szablewski https://phoboslab.org
The MIT License(MIT) - https://github.com/phoboslab/qoi


Credits for currently deprecated code
-------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions make/rebol3.nest
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ include-image-natives: [

include-native-bmp-codec: [config: INCLUDE_BMP_CODEC core-files: %core/u-bmp.c]
include-native-png-codec: [config: INCLUDE_PNG_CODEC core-files: %core/u-png.c]
include-native-qoi-codec: [config: INCLUDE_QOI_CODEC core-files: %core/u-qoi.c]
include-native-jpg-codec: [config: INCLUDE_JPG_CODEC core-files: %core/u-jpg.c]
include-native-gif-codec: [config: INCLUDE_GIF_CODEC core-files: %core/u-gif.c]

Expand Down Expand Up @@ -379,6 +380,7 @@ include-image-codecs: [
#if MacOS? [
:include-image-os-codec
]
:include-native-qoi-codec
mezz-lib-files: %mezz/codec-image-ext.reb ; png/size? function and similar
]

Expand Down
3 changes: 3 additions & 0 deletions src/core/b-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,9 @@ extern const REBYTE Str_Banner[];
#ifdef INCLUDE_PNG_CODEC
Init_PNG_Codec();
#endif
#ifdef INCLUDE_QOI_CODEC
Init_QOI_Codec();
#endif
#ifdef INCLUDE_JPG_CODEC
Init_JPEG_Codec();
#endif
Expand Down
138 changes: 138 additions & 0 deletions src/core/u-qoi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/***********************************************************************
**
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2021 Rebol Open Source Developers
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
************************************************************************
**
** Module: u-qoi.c
** Summary: QOI image format conversion
** Section: utility
**
***********************************************************************
** Base-code:
if find system/codecs 'qoi [
system/codecs/qoi/suffixes: [%.qoi]
append append system/options/file-types system/codecs/qoi/suffixes 'qoi
]
***********************************************************************/
#include "sys-core.h"

#ifdef INCLUDE_QOI_CODEC
#define QOI_IMPLEMENTATION
#define QOI_NO_STDIO
#include "sys-qoi.h"

#define QOI_MALLOC(sz) Make_Mem(sz)
#define QOI_FREE(p) free(p)

/***********************************************************************
**
*/ static void Encode_QOI_Image(REBCDI *codi)
/*
** Input: Image bits (codi->bits, w, h)
** Output: QOI encoded image (codi->data, len)
** Error: Code in codi->error
** Return: Success as TRUE or FALSE
**
***********************************************************************/
{
qoi_desc desc;
desc.width = codi->w;
desc.height = codi->h;
desc.channels = 4;// codi->alpha ? 4 : 3;
desc.colorspace = QOI_SRGB;

codi->data = qoi_encode(codi->bits, &desc, &codi->len);
codi->error = codi->data == NULL ? -1 : 0;
}


/***********************************************************************
**
*/ void Decode_QOI_Image(REBCDI *codi)
/*
** Input: QOI encoded image (codi->data, len)
** Output: Image bits (codi->bits, w, h)
** Error: Code in codi->error
**
***********************************************************************/
{
qoi_desc desc;

codi->bits = qoi_decode(codi->data, codi->len, &desc, 4);
codi->w = desc.width;
codi->h = desc.height;
codi->error = codi->bits == NULL ? -1 : 0;
}

/***********************************************************************
**
*/ void Identify_QOI_Image(REBCDI *codi)
/*
** Input: QOI encoded image (codi->data)
** Output: No error means success
**
***********************************************************************/
{
int p = 0;
unsigned int header_magic = qoi_read_32(codi->data, &p);
codi->error = (header_magic != QOI_MAGIC);
}


/***********************************************************************
**
*/ REBINT Codec_QOI_Image(REBCDI *codi)
/*
***********************************************************************/
{
codi->error = 0;

if (codi->action == CODI_IDENTIFY) {
Identify_QOI_Image(codi);
return CODI_CHECK; // error code is inverted result
}

if (codi->action == CODI_DECODE) {
Decode_QOI_Image(codi);
return CODI_IMAGE;
}

if (codi->action == CODI_ENCODE) {
Encode_QOI_Image(codi);
return CODI_BINARY;
}

codi->error = CODI_ERR_NA;
return CODI_ERROR;
}


/***********************************************************************
**
*/ void Init_QOI_Codec(void)
/*
***********************************************************************/
{
Register_Codec("qoi", Codec_QOI_Image);
}

#endif //INCLUDE_QOI_CODEC
Loading

0 comments on commit 15de62c

Please # to comment.