(* Copyright 2016, 2018, 2020, 2022 KolibriOS team This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . *) MODULE libimg; IMPORT sys := SYSTEM, KOSAPI; CONST FLIP_VERTICAL *= 1; FLIP_HORIZONTAL *= 2; ROTATE_90_CW *= 1; ROTATE_180 *= 2; ROTATE_270_CW *= 3; ROTATE_90_CCW *= ROTATE_270_CW; ROTATE_270_CCW *= ROTATE_90_CW; // scale type corresponding img_scale params LIBIMG_SCALE_INTEGER *= 1; // scale factor ; reserved 0 LIBIMG_SCALE_TILE *= 2; // new width ; new height LIBIMG_SCALE_STRETCH *= 3; // new width ; new height LIBIMG_SCALE_FIT_RECT *= 4; // new width ; new height LIBIMG_SCALE_FIT_WIDTH *= 5; // new width ; new height LIBIMG_SCALE_FIT_HEIGHT *= 6; // new width ; new height LIBIMG_SCALE_FIT_MAX *= 7; // new width ; new height // interpolation algorithm LIBIMG_INTER_NONE *= 0; // use it with LIBIMG_SCALE_INTEGER, LIBIMG_SCALE_TILE, etc LIBIMG_INTER_BILINEAR *= 1; LIBIMG_INTER_DEFAULT *= LIBIMG_INTER_BILINEAR; // list of format id's LIBIMG_FORMAT_BMP *= 1; LIBIMG_FORMAT_ICO *= 2; LIBIMG_FORMAT_CUR *= 3; LIBIMG_FORMAT_GIF *= 4; LIBIMG_FORMAT_PNG *= 5; LIBIMG_FORMAT_JPEG *= 6; LIBIMG_FORMAT_TGA *= 7; LIBIMG_FORMAT_PCX *= 8; LIBIMG_FORMAT_XCF *= 9; LIBIMG_FORMAT_TIFF *= 10; LIBIMG_FORMAT_PNM *= 11; LIBIMG_FORMAT_WBMP *= 12; LIBIMG_FORMAT_XBM *= 13; LIBIMG_FORMAT_Z80 *= 14; // encode flags (byte 0x02 of common option) LIBIMG_ENCODE_STRICT_SPECIFIC *= 01H; LIBIMG_ENCODE_STRICT_BIT_DEPTH *= 02H; LIBIMG_ENCODE_DELETE_ALPHA *= 08H; LIBIMG_ENCODE_FLUSH_ALPHA *= 10H; // values for Image.Type // must be consecutive to allow fast switch on Image.Type in support functions bpp8i *= 1; // indexed bpp24 *= 2; bpp32 *= 3; bpp15 *= 4; bpp16 *= 5; bpp1 *= 6; bpp8g *= 7; // grayscale bpp2i *= 8; bpp4i *= 9; bpp8a *= 10; // grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images // bits in Image.Flags IsAnimated *= 1; TYPE Image* = RECORD Checksum *: INTEGER; Width *: INTEGER; Height *: INTEGER; Next *: INTEGER; Previous *: INTEGER; Type *: INTEGER; // one of bppN Data *: INTEGER; Palette *: INTEGER; // used iff Type eq bpp1, bpp2, bpp4 or bpp8i Extended *: INTEGER; Flags *: INTEGER; // bitfield Delay *: INTEGER // used iff IsAnimated is set in Flags END; ImageDecodeOptions* = RECORD UsedSize *: INTEGER; // if >=8, the field BackgroundColor is valid, and so on BackgroundColor *: INTEGER // used for transparent images as background END; FormatsTableEntry* = RECORD Format_id *: INTEGER; Is *: INTEGER; Decode *: INTEGER; Encode *: INTEGER; Capabilities *: INTEGER END; VAR img_is_img *: PROCEDURE (data, length: INTEGER): INTEGER; img_to_rgb2 *: PROCEDURE (img: INTEGER; out: INTEGER); (* ;;------------------------------------------------------------------------------------------------;; ;? decodes image data into RGB triplets and stores them where out points to ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to source image ;; ;> out = where to store RGB triplets ;; ;;================================================================================================;; *) img_to_rgb *: PROCEDURE (img: INTEGER): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? decodes image data into RGB triplets and returns pointer to memory area containing them ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to source image ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to rgb_data (array of [rgb] triplets) ;; ;;================================================================================================;; *) img_decode *: PROCEDURE (data, length, options: INTEGER): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? decodes loaded into memory graphic file ;; ;;------------------------------------------------------------------------------------------------;; ;> data = pointer to file in memory ;; ;> length = size in bytes of memory area pointed to by data ;; ;> options = 0 / pointer to the structure of additional options ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to image ;; ;;================================================================================================;; *) img_encode *: PROCEDURE (img: INTEGER; common, specific: INTEGER): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? encode image to some format ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to input image ;; ;> common = some most important options ;; ; 0x00 : byte : format id ;; ; 0x01 : byte : fast encoding (0) / best compression ratio (255) ;; ; 0 : store uncompressed data (if supported both by the format and libimg) ;; ; 1 - 255 : use compression, if supported ;; ; this option may be ignored if any format specific options are defined ;; ; i.e. the 0 here will be ignored if some compression algorithm is specified ;; ; 0x02 : byte : flags (bitfield) ;; ; 0x01 : return an error if format specific conditions cannot be met ;; ; 0x02 : preserve current bit depth. means 8bpp/16bpp/24bpp and so on ;; ; 0x04 : delete alpha channel, if any ;; ; 0x08 : flush alpha channel with 0xff, if any; add it if none ;; ; 0x03 : byte : reserved, must be 0 ;; ;> specific = 0 / pointer to the structure of format specific options ;; ; see .inc for description ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to encoded data ;; ;;================================================================================================;; *) img_create *: PROCEDURE (width, height, _type: INTEGER): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? creates an Image structure and initializes some its fields ;; ;;------------------------------------------------------------------------------------------------;; ;> width = width of an image in pixels ;; ;> height = height of an image in pixels ;; ;> type = one of the bppN constants ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to image ;; ;;================================================================================================;; *) img_destroy *: PROCEDURE (img: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? frees memory occupied by an image and all the memory regions its fields point to ;; ;? follows Previous/Next pointers and deletes all the images in sequence ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE (fail) / TRUE (success) ;; ;;================================================================================================;; *) img_destroy_layer *: PROCEDURE (img: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? frees memory occupied by an image and all the memory regions its fields point to ;; ;? for image sequences deletes only one frame and fixes Previous/Next pointers ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE (fail) / TRUE (success) ;; ;;================================================================================================;; *) img_count *: PROCEDURE (img: INTEGER): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? Get number of images in the list (e.g. in animated GIF file) ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;;------------------------------------------------------------------------------------------------;; ;< -1 (fail) / >0 (ok) ;; ;;================================================================================================;; *) img_flip *: PROCEDURE (img: INTEGER; flip_kind: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? Flip all layers of image ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;> flip_kind = one of FLIP_* constants ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE / TRUE ;; ;;================================================================================================;; *) img_flip_layer *: PROCEDURE (img: INTEGER; flip_kind: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? Flip image layer ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;> flip_kind = one of FLIP_* constants ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE / TRUE ;; ;;================================================================================================;; *) img_rotate *: PROCEDURE (img: INTEGER; rotate_kind: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? Rotate all layers of image ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;> rotate_kind = one of ROTATE_* constants ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE / TRUE ;; ;;================================================================================================;; *) img_rotate_layer *: PROCEDURE (img: INTEGER; rotate_kind: INTEGER): BOOLEAN; (* ;;------------------------------------------------------------------------------------------------;; ;? Rotate image layer ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;> rotate_kind = one of ROTATE_* constants ;; ;;------------------------------------------------------------------------------------------------;; ;< FALSE / TRUE ;; ;;================================================================================================;; *) img_draw *: PROCEDURE (img: INTEGER; x, y, width, height, xpos, ypos: INTEGER); (* ;;------------------------------------------------------------------------------------------------;; ;? Draw image in the window ;; ;;------------------------------------------------------------------------------------------------;; ;> img = pointer to image ;; ;> x = x-coordinate in the window ;; ;> y = y-coordinate in the window ;; ;> width = maximum width to draw ;; ;> height = maximum height to draw ;; ;> xpos = offset in image by x-axis ;; ;> ypos = offset in image by y-axis ;; ;;================================================================================================;; *) img_scale *: PROCEDURE (src: INTEGER; crop_x, crop_y, crop_width, crop_height: INTEGER; dst: INTEGER; scale, inter, param1, param2: INTEGER ): INTEGER; (* ;;------------------------------------------------------------------------------------------------;; ;? scale _image ;; ;;------------------------------------------------------------------------------------------------;; ;> src = pointer to source image ;; ;> crop_x = left coord of cropping rect ;; ;> crop_y = top coord of cropping rect ;; ;> crop_width = width of cropping rect ;; ;> crop_height = height of cropping rect ;; ;> dst = pointer to resulting image / 0 ;; ;> scale = how to change width and height. see libimg.inc ;; ;> inter = interpolation algorithm ;; ;> param1 = see libimg.inc ;; ;> param2 = see libimg.inc ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to scaled image ;; ;;================================================================================================;; *) img_convert *: PROCEDURE (src, dst: INTEGER; dst_type, flags, param: INTEGER); (* ;;------------------------------------------------------------------------------------------------;; ;? scale _image ;; ;;------------------------------------------------------------------------------------------------;; ;> src = pointer to source image ;; ;> flags = see libimg.inc ;; ;> dst_type = the Image.Type of converted image ;; ;> dst = pointer to destination image, if any ;; ;;------------------------------------------------------------------------------------------------;; ;< 0 / pointer to converted image ;; ;;================================================================================================;; *) img_formats_table *: ARRAY 20 OF FormatsTableEntry; PROCEDURE GetImageStruct* (img: INTEGER; VAR ImageStruct: Image): BOOLEAN; BEGIN IF img # 0 THEN sys.MOVE(img, sys.ADR(ImageStruct), sys.SIZE(Image)) END RETURN img # 0 END GetImageStruct; PROCEDURE GetFormatsTable(ptr: INTEGER); VAR i: INTEGER; eot: BOOLEAN; BEGIN i := 0; REPEAT sys.MOVE(ptr, sys.ADR(img_formats_table[i]), sys.SIZE(FormatsTableEntry)); ptr := ptr + sys.SIZE(FormatsTableEntry); eot := img_formats_table[i].Format_id = 0; INC(i) UNTIL eot OR (i = LEN(img_formats_table)) END GetFormatsTable; PROCEDURE main; VAR Lib, formats_table_ptr: INTEGER; PROCEDURE GetProc(Lib, v: INTEGER; name: ARRAY OF CHAR); VAR a: INTEGER; BEGIN a := KOSAPI.GetProcAdr(name, Lib); ASSERT(a # 0); sys.PUT(v, a) END GetProc; BEGIN Lib := KOSAPI.LoadLib("/sys/lib/libimg.obj"); ASSERT(Lib # 0); GetProc(Lib, sys.ADR(img_is_img) , "img_is_img"); GetProc(Lib, sys.ADR(img_to_rgb) , "img_to_rgb"); GetProc(Lib, sys.ADR(img_to_rgb2) , "img_to_rgb2"); GetProc(Lib, sys.ADR(img_decode) , "img_decode"); GetProc(Lib, sys.ADR(img_encode) , "img_encode"); GetProc(Lib, sys.ADR(img_create) , "img_create"); GetProc(Lib, sys.ADR(img_destroy) , "img_destroy"); GetProc(Lib, sys.ADR(img_destroy_layer) , "img_destroy_layer"); GetProc(Lib, sys.ADR(img_count) , "img_count"); GetProc(Lib, sys.ADR(img_flip) , "img_flip"); GetProc(Lib, sys.ADR(img_flip_layer) , "img_flip_layer"); GetProc(Lib, sys.ADR(img_rotate) , "img_rotate"); GetProc(Lib, sys.ADR(img_rotate_layer) , "img_rotate_layer"); GetProc(Lib, sys.ADR(img_draw) , "img_draw"); GetProc(Lib, sys.ADR(img_scale) , "img_scale"); GetProc(Lib, sys.ADR(img_convert) , "img_convert"); GetProc(Lib, sys.ADR(formats_table_ptr) , "img_formats_table"); GetFormatsTable(formats_table_ptr) END main; BEGIN main END libimg.