From 49f1b7996c5a754dad949f4fb6043316ac7b75e7 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Wed, 31 Aug 2016 03:08:40 +0300 Subject: [PATCH] watcom build imago.lib --- .gitignore | 6 + Makefile | 21 +- libs/imago/Makefile | 39 ++++ libs/imago/src/file_jpeg.c | 294 ------------------------ libs/imago/src/file_png.c | 262 --------------------- libs/imago/src/file_ppm.c | 153 ------------- libs/imago/src/file_rgbe.c | 501 ----------------------------------------- libs/imago/src/file_tga.c | 250 -------------------- libs/imago/src/filejpeg.c | 294 ++++++++++++++++++++++++ libs/imago/src/filepng.c | 262 +++++++++++++++++++++ libs/imago/src/fileppm.c | 153 +++++++++++++ libs/imago/src/filergbe.c | 501 +++++++++++++++++++++++++++++++++++++++++ libs/imago/src/filetga.c | 250 ++++++++++++++++++++ libs/imago/src/ftmodule.c | 118 ++++++++++ libs/imago/src/ftmodule.h | 39 ++++ libs/imago/src/ftype_module.c | 118 ---------- libs/imago/src/ftype_module.h | 39 ---- libs/imago/src/imago2.c | 2 +- libs/imago/src/inttypes.h | 35 +++ mklibs.bat | 3 + src/dos/keyb.h | 2 + src/tunnel.c | 1 + 22 files changed, 1720 insertions(+), 1623 deletions(-) create mode 100644 libs/imago/Makefile delete mode 100644 libs/imago/src/file_jpeg.c delete mode 100644 libs/imago/src/file_png.c delete mode 100644 libs/imago/src/file_ppm.c delete mode 100644 libs/imago/src/file_rgbe.c delete mode 100644 libs/imago/src/file_tga.c create mode 100644 libs/imago/src/filejpeg.c create mode 100644 libs/imago/src/filepng.c create mode 100644 libs/imago/src/fileppm.c create mode 100644 libs/imago/src/filergbe.c create mode 100644 libs/imago/src/filetga.c create mode 100644 libs/imago/src/ftmodule.c create mode 100644 libs/imago/src/ftmodule.h delete mode 100644 libs/imago/src/ftype_module.c delete mode 100644 libs/imago/src/ftype_module.h create mode 100644 libs/imago/src/inttypes.h create mode 100644 mklibs.bat diff --git a/.gitignore b/.gitignore index 05be71c..8fd165c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,12 @@ *.EXE *.lnk *.LNK +*.lbc +*.LBC +*.lib +*.LIB +*.err +*.ERR *.log *.LOG Debug diff --git a/Makefile b/Makefile index 75dba8d..a78b496 100644 --- a/Makefile +++ b/Makefile @@ -4,20 +4,31 @@ sysobj = gfx.obj vbe.obj dpmi.obj timer.obj keyb.obj mouse.obj logger.obj obj = $(baseobj) $(demoobj) $(sysobj) bin = demo.exe -opt = -5 -fp5 -otexan +libs = imago.lib + +opt = -5 -fp5 -otexan -oh -oi -ei dbg = -d1 +!ifdef __UNIX__ +incpath = -Isrc -Isrc/dos -Ilibs/imago/src +libpath = libs/imago +!else +incpath = -Isrc -Isrc\dos -Ilibs\imago\src +libpath = libs\imago +!endif + AS = nasm CC = wcc386 CXX = wpp386 ASFLAGS = -fobj -CFLAGS = $(dbg) $(opt) -zq -bt=dos -Isrc -Isrc\dos +CFLAGS = $(dbg) $(opt) -zq -bt=dos $(incpath) CXXFLAGS = $(CFLAGS) +LDFLAGS = libpath $(libpath) library { $(libs) } LD = wlink -$(bin): $(obj) - %write objects.lnk system dos4g file { $(obj) } - $(LD) debug all name $@ @objects $(LDFLAGS) +$(bin): $(obj) libs/imago/imago.lib + %write objects.lnk $(obj) + $(LD) debug all name $@ system dos4g file { @objects } $(LDFLAGS) .c: src;src/dos .cc: src;src/dos diff --git a/libs/imago/Makefile b/libs/imago/Makefile new file mode 100644 index 0000000..ada8222 --- /dev/null +++ b/libs/imago/Makefile @@ -0,0 +1,39 @@ +libpng = png.obj pngerror.obj pngget.obj pngmem.obj pngpread.obj pngread.obj & +pngrio.obj pngrtran.obj pngrutil.obj pngset.obj pngtrans.obj pngwio.obj & +pngwrite.obj pngwtran.obj pngwutil.obj +zlib = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj & +inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +jpeglib = jcapimin.obj jcapistd.obj jccoefct.obj jccolor.obj jcdctmgr.obj & +jchuff.obj jcinit.obj jcmainct.obj jcmarker.obj jcmaster.obj jcomapi.obj & +jcparam.obj jcphuff.obj jcprepct.obj jcsample.obj jctrans.obj jdapimin.obj & +jdapistd.obj jdatadst.obj jdatasrc.obj jdcoefct.obj jdcolor.obj jddctmgr.obj & +jdhuff.obj jdinput.obj jdmainct.obj jdmarker.obj jdmaster.obj jdmerge.obj & +jdphuff.obj jdpostct.obj jdsample.obj jdtrans.obj jerror.obj jfdctflt.obj & +jfdctfst.obj jfdctint.obj jidctflt.obj jidctfst.obj jidctint.obj jidctred.obj & +jmemmgr.obj jmemnobs.obj jquant1.obj jquant2.obj jutils.obj + +obj = conv.obj filejpeg.obj filepng.obj fileppm.obj filergbe.obj & +filetga.obj ftmodule.obj imago2.obj imago_gl.obj modules.obj & +$(libpng) $(zlib) $(jpeglib) + +alib = imago.lib + +opt = -5 -fp5 -otexan +dbg = -d1 +def = -DPNG_NO_SNPRINTF + +CC = wcc386 +CFLAGS = $(dbg) $(opt) $(def) -zq -bt=dos -Ilibpng -Izlib -Ijpeglib + +$(alib): $(obj) + %write objects.lbc $(obj) + wlib -b -n $@ @objects + +.c: src;libpng;jpeglib;zlib + +.c.obj: .autodepend + $(CC) -fo=$@ $(CFLAGS) $[* + +clean: .symbolic + del *.obj + del $(alib) diff --git a/libs/imago/src/file_jpeg.c b/libs/imago/src/file_jpeg.c deleted file mode 100644 index bceaf29..0000000 --- a/libs/imago/src/file_jpeg.c +++ /dev/null @@ -1,294 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010 John Tsiombikas - -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 . -*/ - -/* -- JPEG module -- */ - -#include -#include -#include - -#ifdef WIN32 -#include -#define HAVE_BOOLEAN -#endif - -#include -#include "imago2.h" -#include "ftype_module.h" - -#define INPUT_BUF_SIZE 512 -#define OUTPUT_BUF_SIZE 512 - -/* data source manager: adapted from jdatasrc.c */ -struct src_mgr { - struct jpeg_source_mgr pub; - - struct img_io *io; - unsigned char buffer[INPUT_BUF_SIZE]; - int start_of_file; -}; - -/* data destination manager: adapted from jdatadst.c */ -struct dst_mgr { - struct jpeg_destination_mgr pub; - - struct img_io *io; - unsigned char buffer[OUTPUT_BUF_SIZE]; -}; - -static int check(struct img_io *io); -static int read(struct img_pixmap *img, struct img_io *io); -static int write(struct img_pixmap *img, struct img_io *io); - -/* read source functions */ -static void init_source(j_decompress_ptr jd); -static boolean fill_input_buffer(j_decompress_ptr jd); -static void skip_input_data(j_decompress_ptr jd, long num_bytes); -static void term_source(j_decompress_ptr jd); - -/* write destination functions */ -static void init_destination(j_compress_ptr jc); -static boolean empty_output_buffer(j_compress_ptr jc); -static void term_destination(j_compress_ptr jc); - -int img_register_jpeg(void) -{ - static struct ftype_module mod = {".jpg", check, read, write}; - return img_register_module(&mod); -} - - -static int check(struct img_io *io) -{ - unsigned char sig[10]; - - long pos = io->seek(0, SEEK_CUR, io->uptr); - - if(io->read(sig, 10, io->uptr) < 10) { - io->seek(pos, SEEK_SET, io->uptr); - return -1; - } - - if(memcmp(sig, "\xff\xd8\xff\xe0", 4) != 0 && memcmp(sig, "\xff\xd8\xff\xe1", 4) != 0 - && memcmp(sig, "\xff\xd8\xff\xdb", 4) != 0 && memcmp(sig + 6, "JFIF", 4) != 0) { - io->seek(pos, SEEK_SET, io->uptr); - return -1; - } - io->seek(pos, SEEK_SET, io->uptr); - return 0; -} - -static int read(struct img_pixmap *img, struct img_io *io) -{ - int i, nlines = 0; - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - struct src_mgr src; - unsigned char **scanlines; - - io->seek(0, SEEK_CUR, io->uptr); - - cinfo.err = jpeg_std_error(&jerr); /* XXX change... */ - jpeg_create_decompress(&cinfo); - - src.pub.init_source = init_source; - src.pub.fill_input_buffer = fill_input_buffer; - src.pub.skip_input_data = skip_input_data; - src.pub.resync_to_restart = jpeg_resync_to_restart; - src.pub.term_source = term_source; - src.pub.next_input_byte = 0; - src.pub.bytes_in_buffer = 0; - src.io = io; - cinfo.src = (struct jpeg_source_mgr*)&src; - - jpeg_read_header(&cinfo, 1); - cinfo.out_color_space = JCS_RGB; - - if(img_set_pixels(img, cinfo.image_width, cinfo.image_height, IMG_FMT_RGB24, 0) == -1) { - jpeg_destroy_decompress(&cinfo); - return -1; - } - - if(!(scanlines = malloc(img->height * sizeof *scanlines))) { - jpeg_destroy_decompress(&cinfo); - return -1; - } - scanlines[0] = img->pixels; - for(i=1; iheight; i++) { - scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz; - } - - jpeg_start_decompress(&cinfo); - while(nlines < img->height) { - int res = jpeg_read_scanlines(&cinfo, scanlines + nlines, img->height - nlines); - nlines += res; - } - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - free(scanlines); - return 0; -} - -static int write(struct img_pixmap *img, struct img_io *io) -{ - int i, nlines = 0; - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - struct dst_mgr dest; - struct img_pixmap tmpimg; - unsigned char **scanlines; - - img_init(&tmpimg); - - if(img->fmt != IMG_FMT_RGB24) { - if(img_copy(&tmpimg, img) == -1) { - return -1; - } - if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) { - img_destroy(&tmpimg); - return -1; - } - img = &tmpimg; - } - - if(!(scanlines = malloc(img->height * sizeof *scanlines))) { - img_destroy(&tmpimg); - return -1; - } - scanlines[0] = img->pixels; - for(i=1; iheight; i++) { - scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz; - } - - cinfo.err = jpeg_std_error(&jerr); /* XXX */ - jpeg_create_compress(&cinfo); - - dest.pub.init_destination = init_destination; - dest.pub.empty_output_buffer = empty_output_buffer; - dest.pub.term_destination = term_destination; - dest.io = io; - cinfo.dest = (struct jpeg_destination_mgr*)&dest; - - cinfo.image_width = img->width; - cinfo.image_height = img->height; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - - jpeg_set_defaults(&cinfo); - - jpeg_start_compress(&cinfo, 1); - while(nlines < img->height) { - int res = jpeg_write_scanlines(&cinfo, scanlines + nlines, img->height - nlines); - nlines += res; - } - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - - free(scanlines); - img_destroy(&tmpimg); - return 0; -} - -/* -- read source functions -- - * the following functions are adapted from jdatasrc.c in jpeglib - */ -static void init_source(j_decompress_ptr jd) -{ - struct src_mgr *src = (struct src_mgr*)jd->src; - src->start_of_file = 1; -} - -static boolean fill_input_buffer(j_decompress_ptr jd) -{ - struct src_mgr *src = (struct src_mgr*)jd->src; - size_t nbytes; - - nbytes = src->io->read(src->buffer, INPUT_BUF_SIZE, src->io->uptr); - - if(nbytes <= 0) { - if(src->start_of_file) { - return 0; - } - /* insert a fake EOI marker */ - src->buffer[0] = 0xff; - src->buffer[1] = JPEG_EOI; - nbytes = 2; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = 0; - return 1; -} - -static void skip_input_data(j_decompress_ptr jd, long num_bytes) -{ - struct src_mgr *src = (struct src_mgr*)jd->src; - - if(num_bytes > 0) { - while(num_bytes > (long)src->pub.bytes_in_buffer) { - num_bytes -= (long)src->pub.bytes_in_buffer; - fill_input_buffer(jd); - } - src->pub.next_input_byte += (size_t)num_bytes; - src->pub.bytes_in_buffer -= (size_t)num_bytes; - } -} - -static void term_source(j_decompress_ptr jd) -{ - /* nothing to see here, move along */ -} - - -/* -- write destination functions -- - * the following functions are adapted from jdatadst.c in jpeglib - */ -static void init_destination(j_compress_ptr jc) -{ - struct dst_mgr *dest = (struct dst_mgr*)jc->dest; - - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; -} - -static boolean empty_output_buffer(j_compress_ptr jc) -{ - struct dst_mgr *dest = (struct dst_mgr*)jc->dest; - - if(dest->io->write(dest->buffer, OUTPUT_BUF_SIZE, dest->io->uptr) != OUTPUT_BUF_SIZE) { - return 0; - } - - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - return 1; -} - -static void term_destination(j_compress_ptr jc) -{ - struct dst_mgr *dest = (struct dst_mgr*)jc->dest; - size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - - /* write any remaining data in the buffer */ - if(datacount > 0) { - dest->io->write(dest->buffer, datacount, dest->io->uptr); - } - /* XXX flush? ... */ -} diff --git a/libs/imago/src/file_png.c b/libs/imago/src/file_png.c deleted file mode 100644 index 113c542..0000000 --- a/libs/imago/src/file_png.c +++ /dev/null @@ -1,262 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010 John Tsiombikas - -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 . -*/ - -/* -- PNG module -- */ - -#include -#include -#include -#include "imago2.h" -#include "ftype_module.h" - -static int check_file(struct img_io *io); -static int read_file(struct img_pixmap *img, struct img_io *io); -static int write_file(struct img_pixmap *img, struct img_io *io); - -static void read_func(png_struct *png, unsigned char *data, size_t len); -static void write_func(png_struct *png, unsigned char *data, size_t len); -static void flush_func(png_struct *png); - -static int png_type_to_fmt(int color_type, int channel_bits); -static int fmt_to_png_type(enum img_fmt fmt); - - -int img_register_png(void) -{ - static struct ftype_module mod = {".png", check_file, read_file, write_file}; - return img_register_module(&mod); -} - -static int check_file(struct img_io *io) -{ - unsigned char sig[8]; - int res; - long pos = io->seek(0, SEEK_CUR, io->uptr); - - if(io->read(sig, 8, io->uptr) < 8) { - io->seek(pos, SEEK_SET, io->uptr); - return -1; - } - - res = png_sig_cmp(sig, 0, 8) == 0 ? 0 : -1; - io->seek(pos, SEEK_SET, io->uptr); - return res; -} - -static int read_file(struct img_pixmap *img, struct img_io *io) -{ - png_struct *png; - png_info *info; - int channel_bits, color_type, ilace_type, compression, filtering, fmt; - png_uint_32 xsz, ysz; - - if(!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) { - return -1; - } - - if(!(info = png_create_info_struct(png))) { - png_destroy_read_struct(&png, 0, 0); - return -1; - } - - if(setjmp(png_jmpbuf(png))) { - png_destroy_read_struct(&png, &info, 0); - return -1; - } - - png_set_read_fn(png, io, read_func); - png_set_sig_bytes(png, 0); - png_read_png(png, info, 0, 0); - - png_get_IHDR(png, info, &xsz, &ysz, &channel_bits, &color_type, &ilace_type, - &compression, &filtering); - if((fmt = png_type_to_fmt(color_type, channel_bits)) == -1) { - png_destroy_read_struct(&png, &info, 0); - return -1; - } - - if(img_set_pixels(img, xsz, ysz, fmt, 0) == -1) { - png_destroy_read_struct(&png, &info, 0); - return -1; - } - - - if(channel_bits == 8) { - unsigned int i; - unsigned char **lineptr = (unsigned char**)png_get_rows(png, info); - unsigned char *dest = img->pixels; - - for(i=0; ipixelsz); - dest += xsz * img->pixelsz; - } - } else { - unsigned int i, j, num_elem; - unsigned char **lineptr = (unsigned char**)png_get_rows(png, info); - float *dest = img->pixels; - - num_elem = img->pixelsz / sizeof(float); - for(i=0; ifmt); - png_set_IHDR(png, info, img->width, img->height, 8, coltype, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_set_text(png, info, &txt, 1); - - if(!(rows = malloc(img->height * sizeof *rows))) { - png_destroy_write_struct(&png, &info); - img_destroy(&tmpimg); - return -1; - } - - pixptr = img->pixels; - for(i=0; iheight; i++) { - rows[i] = pixptr; - pixptr += img->width * img->pixelsz; - } - png_set_rows(png, info, rows); - - png_write_png(png, info, 0, 0); - png_write_end(png, info); - png_destroy_write_struct(&png, &info); - - free(rows); - - img_destroy(&tmpimg); - return 0; -} - -static void read_func(png_struct *png, unsigned char *data, size_t len) -{ - struct img_io *io = (struct img_io*)png_get_io_ptr(png); - - if(io->read(data, len, io->uptr) == -1) { - longjmp(png_jmpbuf(png), 1); - } -} - -static void write_func(png_struct *png, unsigned char *data, size_t len) -{ - struct img_io *io = (struct img_io*)png_get_io_ptr(png); - - if(io->write(data, len, io->uptr) == -1) { - longjmp(png_jmpbuf(png), 1); - } -} - -static void flush_func(png_struct *png) -{ - /* XXX does it matter that we can't flush? */ -} - -static int png_type_to_fmt(int color_type, int channel_bits) -{ - /* only 8 and 16 bits per channel ar supported at the moment */ - if(channel_bits != 8 && channel_bits != 16) { - return -1; - } - - switch(color_type) { - case PNG_COLOR_TYPE_RGB: - return channel_bits == 16 ? IMG_FMT_RGBF : IMG_FMT_RGB24; - - case PNG_COLOR_TYPE_RGB_ALPHA: - return channel_bits == 16 ? IMG_FMT_RGBAF : IMG_FMT_RGBA32; - - case PNG_COLOR_TYPE_GRAY: - return channel_bits == 16 ? IMG_FMT_GREYF : IMG_FMT_GREY8; - - default: - break; - } - return -1; -} - -static int fmt_to_png_type(enum img_fmt fmt) -{ - switch(fmt) { - case IMG_FMT_GREY8: - return PNG_COLOR_TYPE_GRAY; - - case IMG_FMT_RGB24: - return PNG_COLOR_TYPE_RGB; - - case IMG_FMT_RGBA32: - return PNG_COLOR_TYPE_RGBA; - - default: - break; - } - return -1; -} diff --git a/libs/imago/src/file_ppm.c b/libs/imago/src/file_ppm.c deleted file mode 100644 index ffe1e46..0000000 --- a/libs/imago/src/file_ppm.c +++ /dev/null @@ -1,153 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010 John Tsiombikas - -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 . -*/ - -/* -- Portable Pixmap (PPM) module -- */ - -#include -#include "imago2.h" -#include "ftype_module.h" - -static int check(struct img_io *io); -static int read(struct img_pixmap *img, struct img_io *io); -static int write(struct img_pixmap *img, struct img_io *io); - -int img_register_ppm(void) -{ - static struct ftype_module mod = {".ppm", check, read, write}; - return img_register_module(&mod); -} - - -static int check(struct img_io *io) -{ - char id[2]; - int res = -1; - long pos = io->seek(0, SEEK_CUR, io->uptr); - - if(io->read(id, 2, io->uptr) < 2) { - io->seek(pos, SEEK_SET, io->uptr); - return -1; - } - - if(id[0] == 'P' && (id[1] == '6' || id[1] == '3')) { - res = 0; - } - io->seek(pos, SEEK_SET, io->uptr); - return res; -} - -static int iofgetc(struct img_io *io) -{ - char c; - return io->read(&c, 1, io->uptr) < 1 ? -1 : c; -} - -static char *iofgets(char *buf, int size, struct img_io *io) -{ - int c; - char *ptr = buf; - - while(--size > 0 && (c = iofgetc(io)) != -1) { - *ptr++ = c; - if(c == '\n') break; - } - *ptr = 0; - - return ptr == buf ? 0 : buf; -} - -/* TODO: implement P3 reading */ -static int read(struct img_pixmap *img, struct img_io *io) -{ - char buf[256]; - int xsz, ysz, maxval, got_hdrlines = 1; - - if(!iofgets(buf, sizeof buf, io)) { - return -1; - } - if(!(buf[0] == 'P' && (buf[1] == '6' || buf[1] == '3'))) { - return -1; - } - - while(got_hdrlines < 3 && iofgets(buf, sizeof buf, io)) { - if(buf[0] == '#') continue; - - switch(got_hdrlines) { - case 1: - if(sscanf(buf, "%d %d\n", &xsz, &ysz) < 2) { - return -1; - } - break; - - case 2: - if(sscanf(buf, "%d\n", &maxval) < 1) { - return -1; - } - default: - break; - } - got_hdrlines++; - } - - if(xsz < 1 || ysz < 1 || maxval != 255) { - return -1; - } - - if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGB24, 0) == -1) { - return -1; - } - - if(io->read(img->pixels, xsz * ysz * 3, io->uptr) < (unsigned int)(xsz * ysz * 3)) { - return -1; - } - return 0; -} - -static int write(struct img_pixmap *img, struct img_io *io) -{ - int sz; - char buf[256]; - struct img_pixmap tmpimg; - - img_init(&tmpimg); - - if(img->fmt != IMG_FMT_RGB24) { - if(img_copy(&tmpimg, img) == -1) { - return -1; - } - if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) { - return -1; - } - img = &tmpimg; - } - - sprintf(buf, "P6\n#written by libimago2\n%d %d\n255\n", img->width, img->height); - if(io->write(buf, strlen(buf), io->uptr) < strlen(buf)) { - img_destroy(&tmpimg); - return -1; - } - - sz = img->width * img->height * 3; - if(io->write(img->pixels, sz, io->uptr) < (unsigned int)sz) { - img_destroy(&tmpimg); - return -1; - } - - img_destroy(&tmpimg); - return 0; -} diff --git a/libs/imago/src/file_rgbe.c b/libs/imago/src/file_rgbe.c deleted file mode 100644 index 16f8efa..0000000 --- a/libs/imago/src/file_rgbe.c +++ /dev/null @@ -1,501 +0,0 @@ -/* This file contains code to read and write four byte rgbe file format - * developed by Greg Ward. It handles the conversions between rgbe and - * pixels consisting of floats. The data is assumed to be an array of floats. - * By default there are three floats per pixel in the order red, green, blue. - * (RGBE_DATA_??? values control this.) - * - * written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95 - * based on code written by Greg Ward - * minor modifications by John Tsiombikas (nuclear@member.fsf.org) apr.9 2007 - */ - -#include -#include -#include -#include -#include -#include -#include "imago2.h" -#include "ftype_module.h" - - -typedef struct { - int valid; /* indicate which fields are valid */ - char programtype[16]; /* listed at beginning of file to identify it - * after "#?". defaults to "RGBE" */ - float gamma; /* image has already been gamma corrected with - * given gamma. defaults to 1.0 (no correction) */ - float exposure; /* a value of 1.0 in an image corresponds to - * watts/steradian/m^2. - * defaults to 1.0 */ -} rgbe_header_info; - - -static int check(struct img_io *io); -static int read(struct img_pixmap *img, struct img_io *io); -static int write(struct img_pixmap *img, struct img_io *io); - -static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info); -static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines); - - -int img_register_rgbe(void) -{ - static struct ftype_module mod = {".rgbe", check, read, write}; - return img_register_module(&mod); -} - - -static int check(struct img_io *io) -{ - int xsz, ysz, res; - long pos = io->seek(0, SEEK_CUR, io->uptr); - - rgbe_header_info hdr; - res = rgbe_read_header(io, &xsz, &ysz, &hdr); - - io->seek(pos, SEEK_SET, io->uptr); - return res; -} - -static int read(struct img_pixmap *img, struct img_io *io) -{ - int xsz, ysz; - rgbe_header_info hdr; - - if(rgbe_read_header(io, &xsz, &ysz, &hdr) == -1) { - return -1; - } - - if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGBF, 0) == -1) { - return -1; - } - if(rgbe_read_pixels_rle(io, img->pixels, xsz, ysz) == -1) { - return -1; - } - return 0; -} - -static int write(struct img_pixmap *img, struct img_io *io) -{ - return -1; /* TODO */ -} - - -static int iofgetc(struct img_io *io) -{ - char c; - return io->read(&c, 1, io->uptr) < 1 ? -1 : c; -} - -static char *iofgets(char *buf, int size, struct img_io *io) -{ - int c; - char *ptr = buf; - - while(--size > 0 && (c = iofgetc(io)) != -1) { - *ptr++ = c; - if(c == '\n') break; - } - *ptr = 0; - - return ptr == buf ? 0 : buf; -} - - -/* flags indicating which fields in an rgbe_header_info are valid */ -#define RGBE_VALID_PROGRAMTYPE 0x01 -#define RGBE_VALID_GAMMA 0x02 -#define RGBE_VALID_EXPOSURE 0x04 - -/* return codes for rgbe routines */ -#define RGBE_RETURN_SUCCESS 0 -#define RGBE_RETURN_FAILURE -1 - - -#if defined(__cplusplus) || defined(GNUC) || __STDC_VERSION >= 199901L -#define INLINE inline -#else -#define INLINE -#endif - -/* offsets to red, green, and blue components in a data (float) pixel */ -#define RGBE_DATA_RED 0 -#define RGBE_DATA_GREEN 1 -#define RGBE_DATA_BLUE 2 - -/* number of floats per pixel */ -#define RGBE_DATA_SIZE 3 - -enum rgbe_error_codes { - rgbe_read_error, - rgbe_write_error, - rgbe_format_error, - rgbe_memory_error -}; - - -/* default error routine. change this to change error handling */ -static int rgbe_error(int rgbe_error_code, char *msg) -{ - switch (rgbe_error_code) { - case rgbe_read_error: - fprintf(stderr, "RGBE read error: %s\n", strerror(errno)); - break; - - case rgbe_write_error: - fprintf(stderr, "RGBE write error: %s\n", strerror(errno)); - break; - - case rgbe_format_error: - fprintf(stderr, "RGBE bad file format: %s\n", msg); - break; - - default: - case rgbe_memory_error: - fprintf(stderr, "RGBE error: %s\n", msg); - } - return RGBE_RETURN_FAILURE; -} - -/* standard conversion from float pixels to rgbe pixels */ -/*static INLINE void float2rgbe(unsigned char rgbe[4], float red, float green, float blue) -{ - float v; - int e; - - v = red; - if(green > v) - v = green; - if(blue > v) - v = blue; - if(v < 1e-32) { - rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; - } else { - v = frexp(v, &e) * 256.0 / v; - rgbe[0] = (unsigned char)(red * v); - rgbe[1] = (unsigned char)(green * v); - rgbe[2] = (unsigned char)(blue * v); - rgbe[3] = (unsigned char)(e + 128); - } -}*/ - -/* standard conversion from rgbe to float pixels */ -/* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */ -/* in the range [0,1] to map back into the range [0,1]. */ -static INLINE void rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4]) -{ - float f; - - if(rgbe[3]) { /*nonzero pixel */ - f = ldexp(1.0, rgbe[3] - (int)(128 + 8)); - *red = rgbe[0] * f; - *green = rgbe[1] * f; - *blue = rgbe[2] * f; - } else - *red = *green = *blue = 0.0; -} - -#if 0 -/* default minimal header. modify if you want more information in header */ -static int rgbe_write_header(FILE * fp, int width, int height, rgbe_header_info * info) -{ - char *programtype = "RGBE"; - - if(info && (info->valid & RGBE_VALID_PROGRAMTYPE)) - programtype = info->programtype; - if(fprintf(fp, "#?%s\n", programtype) < 0) - return rgbe_error(rgbe_write_error, NULL); - /* The #? is to identify file type, the programtype is optional. */ - if(info && (info->valid & RGBE_VALID_GAMMA)) { - if(fprintf(fp, "GAMMA=%g\n", info->gamma) < 0) - return rgbe_error(rgbe_write_error, NULL); - } - if(info && (info->valid & RGBE_VALID_EXPOSURE)) { - if(fprintf(fp, "EXPOSURE=%g\n", info->exposure) < 0) - return rgbe_error(rgbe_write_error, NULL); - } - if(fprintf(fp, "FORMAT=32-bit_rle_rgbe\n\n") < 0) - return rgbe_error(rgbe_write_error, NULL); - if(fprintf(fp, "-Y %d +X %d\n", height, width) < 0) - return rgbe_error(rgbe_write_error, NULL); - return RGBE_RETURN_SUCCESS; -} -#endif - -/* minimal header reading. modify if you want to parse more information */ -static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info) -{ - char buf[128]; - float tempf; - int i; - - if(info) { - info->valid = 0; - info->programtype[0] = 0; - info->gamma = info->exposure = 1.0; - } - if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == NULL) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ - if((buf[0] != '#') || (buf[1] != '?')) { - /* if you want to require the magic token then uncomment the next line */ - /*return rgbe_error(rgbe_format_error,"bad initial token"); */ - } else if(info) { - info->valid |= RGBE_VALID_PROGRAMTYPE; - for(i = 0; i < sizeof(info->programtype) - 1; i++) { - if((buf[i + 2] == 0) || isspace(buf[i + 2])) - break; - info->programtype[i] = buf[i + 2]; - } - info->programtype[i] = 0; - if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) - return rgbe_error(rgbe_read_error, NULL); - } - for(;;) { - if((buf[0] == 0) || (buf[0] == '\n')) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "no FORMAT specifier found");*/ - else if(strcmp(buf, "FORMAT=32-bit_rle_rgbe\n") == 0) - break; /* format found so break out of loop */ - else if(info && (sscanf(buf, "GAMMA=%g", &tempf) == 1)) { - info->gamma = tempf; - info->valid |= RGBE_VALID_GAMMA; - } else if(info && (sscanf(buf, "EXPOSURE=%g", &tempf) == 1)) { - info->exposure = tempf; - info->valid |= RGBE_VALID_EXPOSURE; - } - if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ - } - if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ - if(strcmp(buf, "\n") != 0) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing blank line after FORMAT specifier");*/ - if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ - if(sscanf(buf, "-Y %d +X %d", height, width) < 2) - return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing image size specifier");*/ - return RGBE_RETURN_SUCCESS; -} - -#if 0 -/* simple write routine that does not use run length encoding */ - -/* These routines can be made faster by allocating a larger buffer and - fread-ing and fwrite-ing the data in larger chunks */ -static int rgbe_write_pixels(FILE * fp, float *data, int numpixels) -{ - unsigned char rgbe[4]; - - while(numpixels-- > 0) { - float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]); - data += RGBE_DATA_SIZE; - if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) - return rgbe_error(rgbe_write_error, NULL); - } - return RGBE_RETURN_SUCCESS; -} -#endif - -/* simple read routine. will not correctly handle run length encoding */ -static int rgbe_read_pixels(struct img_io *io, float *data, int numpixels) -{ - unsigned char rgbe[4]; - - while(numpixels-- > 0) { - if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) - return rgbe_error(rgbe_read_error, NULL); - rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe); - data += RGBE_DATA_SIZE; - } - return RGBE_RETURN_SUCCESS; -} - -#if 0 -/* The code below is only needed for the run-length encoded files. */ - -/* Run length encoding adds considerable complexity but does */ - -/* save some space. For each scanline, each channel (r,g,b,e) is */ - -/* encoded separately for better compression. */ - -static int rgbe_write_bytes_rle(struct img_io *io, unsigned char *data, int numbytes) -{ -#define MINRUNLENGTH 4 - int cur, beg_run, run_count, old_run_count, nonrun_count; - unsigned char buf[2]; - - cur = 0; - while(cur < numbytes) { - beg_run = cur; - /* find next run of length at least 4 if one exists */ - run_count = old_run_count = 0; - while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) { - beg_run += run_count; - old_run_count = run_count; - run_count = 1; - while((beg_run + run_count < numbytes) && (run_count < 127) - && (data[beg_run] == data[beg_run + run_count])) - run_count++; - } - /* if data before next big run is a short run then write it as such */ - if((old_run_count > 1) && (old_run_count == beg_run - cur)) { - buf[0] = 128 + old_run_count; /*write short run */ - buf[1] = data[cur]; - if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1) - return rgbe_error(rgbe_write_error, NULL); - cur = beg_run; - } - /* write out bytes until we reach the start of the next run */ - while(cur < beg_run) { - nonrun_count = beg_run - cur; - if(nonrun_count > 128) - nonrun_count = 128; - buf[0] = nonrun_count; - if(fwrite(buf, sizeof(buf[0]), 1, fp) < 1) - return rgbe_error(rgbe_write_error, NULL); - if(fwrite(&data[cur], sizeof(data[0]) * nonrun_count, 1, fp) < 1) - return rgbe_error(rgbe_write_error, NULL); - cur += nonrun_count; - } - /* write out next run if one was found */ - if(run_count >= MINRUNLENGTH) { - buf[0] = 128 + run_count; - buf[1] = data[beg_run]; - if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1) - return rgbe_error(rgbe_write_error, NULL); - cur += run_count; - } - } - return RGBE_RETURN_SUCCESS; -#undef MINRUNLENGTH -} - -static int rgbe_write_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines) -{ - unsigned char rgbe[4]; - unsigned char *buffer; - int i, err; - - if((scanline_width < 8) || (scanline_width > 0x7fff)) - /* run length encoding is not allowed so write flat */ - return rgbe_write_pixels(io, data, scanline_width * num_scanlines); - buffer = (unsigned char *)malloc(sizeof(unsigned char) * 4 * scanline_width); - if(buffer == NULL) - /* no buffer space so write flat */ - return rgbe_write_pixels(fp, data, scanline_width * num_scanlines); - while(num_scanlines-- > 0) { - rgbe[0] = 2; - rgbe[1] = 2; - rgbe[2] = scanline_width >> 8; - rgbe[3] = scanline_width & 0xFF; - if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) { - free(buffer); - return rgbe_error(rgbe_write_error, NULL); - } - for(i = 0; i < scanline_width; i++) { - float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]); - buffer[i] = rgbe[0]; - buffer[i + scanline_width] = rgbe[1]; - buffer[i + 2 * scanline_width] = rgbe[2]; - buffer[i + 3 * scanline_width] = rgbe[3]; - data += RGBE_DATA_SIZE; - } - /* write out each of the four channels separately run length encoded */ - /* first red, then green, then blue, then exponent */ - for(i = 0; i < 4; i++) { - if((err = rgbe_write_bytes_rle(fp, &buffer[i * scanline_width], - scanline_width)) != RGBE_RETURN_SUCCESS) { - free(buffer); - return err; - } - } - } - free(buffer); - return RGBE_RETURN_SUCCESS; -} -#endif - -static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines) -{ - unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end; - int i, count; - unsigned char buf[2]; - - if((scanline_width < 8) || (scanline_width > 0x7fff)) - /* run length encoding is not allowed so read flat */ - return rgbe_read_pixels(io, data, scanline_width * num_scanlines); - scanline_buffer = NULL; - /* read in each successive scanline */ - while(num_scanlines > 0) { - if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - if((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) { - /* this file is not run length encoded */ - rgbe2float(&data[0], &data[1], &data[2], rgbe); - data += RGBE_DATA_SIZE; - free(scanline_buffer); - return rgbe_read_pixels(io, data, scanline_width * num_scanlines - 1); - } - if((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "wrong scanline width"); - } - if(scanline_buffer == NULL) - scanline_buffer = (unsigned char *) - malloc(sizeof(unsigned char) * 4 * scanline_width); - if(scanline_buffer == NULL) - return rgbe_error(rgbe_memory_error, "unable to allocate buffer space"); - - ptr = &scanline_buffer[0]; - /* read each of the four channels for the scanline into the buffer */ - for(i = 0; i < 4; i++) { - ptr_end = &scanline_buffer[(i + 1) * scanline_width]; - while(ptr < ptr_end) { - if(io->read(buf, sizeof(buf[0]) * 2, io->uptr) < 1) { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - if(buf[0] > 128) { - /* a run of the same value */ - count = buf[0] - 128; - if((count == 0) || (count > ptr_end - ptr)) { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "bad scanline data"); - } - while(count-- > 0) - *ptr++ = buf[1]; - } else { - /* a non-run */ - count = buf[0]; - if((count == 0) || (count > ptr_end - ptr)) { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "bad scanline data"); - } - *ptr++ = buf[1]; - if(--count > 0) { - if(io->read(ptr, sizeof(*ptr) * count, io->uptr) < 1) { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - ptr += count; - } - } - } - } - /* now convert data from buffer into floats */ - for(i = 0; i < scanline_width; i++) { - rgbe[0] = scanline_buffer[i]; - rgbe[1] = scanline_buffer[i + scanline_width]; - rgbe[2] = scanline_buffer[i + 2 * scanline_width]; - rgbe[3] = scanline_buffer[i + 3 * scanline_width]; - rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe); - data += RGBE_DATA_SIZE; - } - num_scanlines--; - } - free(scanline_buffer); - return RGBE_RETURN_SUCCESS; -} diff --git a/libs/imago/src/file_tga.c b/libs/imago/src/file_tga.c deleted file mode 100644 index a563e36..0000000 --- a/libs/imago/src/file_tga.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010-2015 John Tsiombikas - -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 . -*/ - -/* -- Targa (tga) module -- */ - -#include -#include -#include -#include "imago2.h" -#include "ftype_module.h" - - -#if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \ - (defined(__alpha__) || defined(__alpha)) || \ - defined(__arm__) || \ - (defined(__mips__) && defined(__MIPSEL__)) || \ - defined(__SYMBIAN32__) || \ - defined(__x86_64__) || \ - defined(__LITTLE_ENDIAN__) -/* little endian */ -#define read_int16_le(f) read_int16(f) -#else -/* big endian */ -#define read_int16_le(f) read_int16_inv(f) -#endif /* endian check */ - - -enum { - IMG_NONE, - IMG_CMAP, - IMG_RGBA, - IMG_BW, - - IMG_RLE_CMAP = 9, - IMG_RLE_RGBA, - IMG_RLE_BW -}; - -#define IS_RLE(x) ((x) >= IMG_RLE_CMAP) -#define IS_RGBA(x) ((x) == IMG_RGBA || (x) == IMG_RLE_RGBA) - - -struct tga_header { - uint8_t idlen; /* id field length */ - uint8_t cmap_type; /* color map type (0:no color map, 1:color map present) */ - uint8_t img_type; /* image type: - * 0: no image data - * 1: uncomp. color-mapped 9: RLE color-mapped - * 2: uncomp. true color 10: RLE true color - * 3: uncomp. black/white 11: RLE black/white */ - uint16_t cmap_first; /* color map first entry index */ - uint16_t cmap_len; /* color map length */ - uint8_t cmap_entry_sz; /* color map entry size */ - uint16_t img_x; /* X-origin of the image */ - uint16_t img_y; /* Y-origin of the image */ - uint16_t img_width; /* image width */ - uint16_t img_height; /* image height */ - uint8_t img_bpp; /* bits per pixel */ - uint8_t img_desc; /* descriptor: - * bits 0 - 3: alpha or overlay bits - * bits 5 & 4: origin (0 = bottom/left, 1 = top/right) - * bits 7 & 6: data interleaving */ -}; - -struct tga_footer { - uint32_t ext_off; /* extension area offset */ - uint32_t devdir_off; /* developer directory offset */ - char sig[18]; /* signature with . and \0 */ -}; - - -static int check(struct img_io *io); -static int read(struct img_pixmap *img, struct img_io *io); -static int write(struct img_pixmap *img, struct img_io *io); -static int read_pixel(struct img_io *io, int rdalpha, uint32_t *pix); -static int16_t read_int16(struct img_io *io); -static int16_t read_int16_inv(struct img_io *io); - -int img_register_tga(void) -{ - static struct ftype_module mod = {".tga", check, read, write}; - return img_register_module(&mod); -} - - -static int check(struct img_io *io) -{ - struct tga_footer foot; - int res = -1; - long pos = io->seek(0, SEEK_CUR, io->uptr); - io->seek(-18, SEEK_END, io->uptr); - - if(io->read(foot.sig, 17, io->uptr) < 17) { - io->seek(pos, SEEK_SET, io->uptr); - return -1; - } - - if(memcmp(foot.sig, "TRUEVISION-XFILE.", 17) == 0) { - res = 0; - } - io->seek(pos, SEEK_SET, io->uptr); - return res; -} - -static int iofgetc(struct img_io *io) -{ - char c; - return io->read(&c, 1, io->uptr) < 1 ? -1 : c; -} - -static int read(struct img_pixmap *img, struct img_io *io) -{ - struct tga_header hdr; - int x, y; - int i, c; - uint32_t ppixel = 0; - int rle_mode = 0, rle_pix_left = 0; - int rdalpha; - - /* read header */ - hdr.idlen = iofgetc(io); - hdr.cmap_type = iofgetc(io); - hdr.img_type = iofgetc(io); - hdr.cmap_first = read_int16_le(io); - hdr.cmap_len = read_int16_le(io); - hdr.cmap_entry_sz = iofgetc(io); - hdr.img_x = read_int16_le(io); - hdr.img_y = read_int16_le(io); - hdr.img_width = read_int16_le(io); - hdr.img_height = read_int16_le(io); - hdr.img_bpp = iofgetc(io); - if((c = iofgetc(io)) == -1) { - return -1; - } - hdr.img_desc = c; - - if(!IS_RGBA(hdr.img_type)) { - fprintf(stderr, "only true color tga images supported\n"); - return -1; - } - - io->seek(hdr.idlen, SEEK_CUR, io); /* skip the image ID */ - - /* skip the color map if it exists */ - if(hdr.cmap_type == 1) { - io->seek(hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR, io); - } - - x = hdr.img_width; - y = hdr.img_height; - rdalpha = hdr.img_desc & 0xf; - - /* TODO make this IMG_FMT_RGB24 if there's no alpha channel */ - if(img_set_pixels(img, x, y, IMG_FMT_RGBA32, 0) == -1) { - return -1; - } - - for(i=0; ipixels + ((hdr.img_desc & 0x20) ? i : y - (i + 1)) * x; - - for(j=0; jread(&v, 2, io); - return v; -} - -static int16_t read_int16_inv(struct img_io *io) -{ - int16_t v; - io->read(&v, 2, io); - return ((v >> 8) & 0xff) | (v << 8); -} diff --git a/libs/imago/src/filejpeg.c b/libs/imago/src/filejpeg.c new file mode 100644 index 0000000..84a418e --- /dev/null +++ b/libs/imago/src/filejpeg.c @@ -0,0 +1,294 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010 John Tsiombikas + +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 . +*/ + +/* -- JPEG module -- */ + +#include +#include +#include + +#ifdef WIN32 +#include +#define HAVE_BOOLEAN +#endif + +#include +#include "imago2.h" +#include "ftmodule.h" + +#define INPUT_BUF_SIZE 512 +#define OUTPUT_BUF_SIZE 512 + +/* data source manager: adapted from jdatasrc.c */ +struct src_mgr { + struct jpeg_source_mgr pub; + + struct img_io *io; + unsigned char buffer[INPUT_BUF_SIZE]; + int start_of_file; +}; + +/* data destination manager: adapted from jdatadst.c */ +struct dst_mgr { + struct jpeg_destination_mgr pub; + + struct img_io *io; + unsigned char buffer[OUTPUT_BUF_SIZE]; +}; + +static int check(struct img_io *io); +static int read(struct img_pixmap *img, struct img_io *io); +static int write(struct img_pixmap *img, struct img_io *io); + +/* read source functions */ +static void init_source(j_decompress_ptr jd); +static boolean fill_input_buffer(j_decompress_ptr jd); +static void skip_input_data(j_decompress_ptr jd, long num_bytes); +static void term_source(j_decompress_ptr jd); + +/* write destination functions */ +static void init_destination(j_compress_ptr jc); +static boolean empty_output_buffer(j_compress_ptr jc); +static void term_destination(j_compress_ptr jc); + +int img_register_jpeg(void) +{ + static struct ftype_module mod = {".jpg", check, read, write}; + return img_register_module(&mod); +} + + +static int check(struct img_io *io) +{ + unsigned char sig[10]; + + long pos = io->seek(0, SEEK_CUR, io->uptr); + + if(io->read(sig, 10, io->uptr) < 10) { + io->seek(pos, SEEK_SET, io->uptr); + return -1; + } + + if(memcmp(sig, "\xff\xd8\xff\xe0", 4) != 0 && memcmp(sig, "\xff\xd8\xff\xe1", 4) != 0 + && memcmp(sig, "\xff\xd8\xff\xdb", 4) != 0 && memcmp(sig + 6, "JFIF", 4) != 0) { + io->seek(pos, SEEK_SET, io->uptr); + return -1; + } + io->seek(pos, SEEK_SET, io->uptr); + return 0; +} + +static int read(struct img_pixmap *img, struct img_io *io) +{ + int i, nlines = 0; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct src_mgr src; + unsigned char **scanlines; + + io->seek(0, SEEK_CUR, io->uptr); + + cinfo.err = jpeg_std_error(&jerr); /* XXX change... */ + jpeg_create_decompress(&cinfo); + + src.pub.init_source = init_source; + src.pub.fill_input_buffer = fill_input_buffer; + src.pub.skip_input_data = skip_input_data; + src.pub.resync_to_restart = jpeg_resync_to_restart; + src.pub.term_source = term_source; + src.pub.next_input_byte = 0; + src.pub.bytes_in_buffer = 0; + src.io = io; + cinfo.src = (struct jpeg_source_mgr*)&src; + + jpeg_read_header(&cinfo, 1); + cinfo.out_color_space = JCS_RGB; + + if(img_set_pixels(img, cinfo.image_width, cinfo.image_height, IMG_FMT_RGB24, 0) == -1) { + jpeg_destroy_decompress(&cinfo); + return -1; + } + + if(!(scanlines = malloc(img->height * sizeof *scanlines))) { + jpeg_destroy_decompress(&cinfo); + return -1; + } + scanlines[0] = img->pixels; + for(i=1; iheight; i++) { + scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz; + } + + jpeg_start_decompress(&cinfo); + while(nlines < img->height) { + int res = jpeg_read_scanlines(&cinfo, scanlines + nlines, img->height - nlines); + nlines += res; + } + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + free(scanlines); + return 0; +} + +static int write(struct img_pixmap *img, struct img_io *io) +{ + int i, nlines = 0; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + struct dst_mgr dest; + struct img_pixmap tmpimg; + unsigned char **scanlines; + + img_init(&tmpimg); + + if(img->fmt != IMG_FMT_RGB24) { + if(img_copy(&tmpimg, img) == -1) { + return -1; + } + if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) { + img_destroy(&tmpimg); + return -1; + } + img = &tmpimg; + } + + if(!(scanlines = malloc(img->height * sizeof *scanlines))) { + img_destroy(&tmpimg); + return -1; + } + scanlines[0] = img->pixels; + for(i=1; iheight; i++) { + scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz; + } + + cinfo.err = jpeg_std_error(&jerr); /* XXX */ + jpeg_create_compress(&cinfo); + + dest.pub.init_destination = init_destination; + dest.pub.empty_output_buffer = empty_output_buffer; + dest.pub.term_destination = term_destination; + dest.io = io; + cinfo.dest = (struct jpeg_destination_mgr*)&dest; + + cinfo.image_width = img->width; + cinfo.image_height = img->height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + + jpeg_start_compress(&cinfo, 1); + while(nlines < img->height) { + int res = jpeg_write_scanlines(&cinfo, scanlines + nlines, img->height - nlines); + nlines += res; + } + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + free(scanlines); + img_destroy(&tmpimg); + return 0; +} + +/* -- read source functions -- + * the following functions are adapted from jdatasrc.c in jpeglib + */ +static void init_source(j_decompress_ptr jd) +{ + struct src_mgr *src = (struct src_mgr*)jd->src; + src->start_of_file = 1; +} + +static boolean fill_input_buffer(j_decompress_ptr jd) +{ + struct src_mgr *src = (struct src_mgr*)jd->src; + size_t nbytes; + + nbytes = src->io->read(src->buffer, INPUT_BUF_SIZE, src->io->uptr); + + if(nbytes <= 0) { + if(src->start_of_file) { + return 0; + } + /* insert a fake EOI marker */ + src->buffer[0] = 0xff; + src->buffer[1] = JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = 0; + return 1; +} + +static void skip_input_data(j_decompress_ptr jd, long num_bytes) +{ + struct src_mgr *src = (struct src_mgr*)jd->src; + + if(num_bytes > 0) { + while(num_bytes > (long)src->pub.bytes_in_buffer) { + num_bytes -= (long)src->pub.bytes_in_buffer; + fill_input_buffer(jd); + } + src->pub.next_input_byte += (size_t)num_bytes; + src->pub.bytes_in_buffer -= (size_t)num_bytes; + } +} + +static void term_source(j_decompress_ptr jd) +{ + /* nothing to see here, move along */ +} + + +/* -- write destination functions -- + * the following functions are adapted from jdatadst.c in jpeglib + */ +static void init_destination(j_compress_ptr jc) +{ + struct dst_mgr *dest = (struct dst_mgr*)jc->dest; + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + +static boolean empty_output_buffer(j_compress_ptr jc) +{ + struct dst_mgr *dest = (struct dst_mgr*)jc->dest; + + if(dest->io->write(dest->buffer, OUTPUT_BUF_SIZE, dest->io->uptr) != OUTPUT_BUF_SIZE) { + return 0; + } + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + return 1; +} + +static void term_destination(j_compress_ptr jc) +{ + struct dst_mgr *dest = (struct dst_mgr*)jc->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* write any remaining data in the buffer */ + if(datacount > 0) { + dest->io->write(dest->buffer, datacount, dest->io->uptr); + } + /* XXX flush? ... */ +} diff --git a/libs/imago/src/filepng.c b/libs/imago/src/filepng.c new file mode 100644 index 0000000..1d7fe25 --- /dev/null +++ b/libs/imago/src/filepng.c @@ -0,0 +1,262 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010 John Tsiombikas + +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 . +*/ + +/* -- PNG module -- */ + +#include +#include +#include +#include "imago2.h" +#include "ftmodule.h" + +static int check_file(struct img_io *io); +static int read_file(struct img_pixmap *img, struct img_io *io); +static int write_file(struct img_pixmap *img, struct img_io *io); + +static void read_func(png_struct *png, unsigned char *data, size_t len); +static void write_func(png_struct *png, unsigned char *data, size_t len); +static void flush_func(png_struct *png); + +static int png_type_to_fmt(int color_type, int channel_bits); +static int fmt_to_png_type(enum img_fmt fmt); + + +int img_register_png(void) +{ + static struct ftype_module mod = {".png", check_file, read_file, write_file}; + return img_register_module(&mod); +} + +static int check_file(struct img_io *io) +{ + unsigned char sig[8]; + int res; + long pos = io->seek(0, SEEK_CUR, io->uptr); + + if(io->read(sig, 8, io->uptr) < 8) { + io->seek(pos, SEEK_SET, io->uptr); + return -1; + } + + res = png_sig_cmp(sig, 0, 8) == 0 ? 0 : -1; + io->seek(pos, SEEK_SET, io->uptr); + return res; +} + +static int read_file(struct img_pixmap *img, struct img_io *io) +{ + png_struct *png; + png_info *info; + int channel_bits, color_type, ilace_type, compression, filtering, fmt; + png_uint_32 xsz, ysz; + + if(!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) { + return -1; + } + + if(!(info = png_create_info_struct(png))) { + png_destroy_read_struct(&png, 0, 0); + return -1; + } + + if(setjmp(png_jmpbuf(png))) { + png_destroy_read_struct(&png, &info, 0); + return -1; + } + + png_set_read_fn(png, io, read_func); + png_set_sig_bytes(png, 0); + png_read_png(png, info, 0, 0); + + png_get_IHDR(png, info, &xsz, &ysz, &channel_bits, &color_type, &ilace_type, + &compression, &filtering); + if((fmt = png_type_to_fmt(color_type, channel_bits)) == -1) { + png_destroy_read_struct(&png, &info, 0); + return -1; + } + + if(img_set_pixels(img, xsz, ysz, fmt, 0) == -1) { + png_destroy_read_struct(&png, &info, 0); + return -1; + } + + + if(channel_bits == 8) { + unsigned int i; + unsigned char **lineptr = (unsigned char**)png_get_rows(png, info); + unsigned char *dest = img->pixels; + + for(i=0; ipixelsz); + dest += xsz * img->pixelsz; + } + } else { + unsigned int i, j, num_elem; + unsigned char **lineptr = (unsigned char**)png_get_rows(png, info); + float *dest = img->pixels; + + num_elem = img->pixelsz / sizeof(float); + for(i=0; ifmt); + png_set_IHDR(png, info, img->width, img->height, 8, coltype, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_text(png, info, &txt, 1); + + if(!(rows = malloc(img->height * sizeof *rows))) { + png_destroy_write_struct(&png, &info); + img_destroy(&tmpimg); + return -1; + } + + pixptr = img->pixels; + for(i=0; iheight; i++) { + rows[i] = pixptr; + pixptr += img->width * img->pixelsz; + } + png_set_rows(png, info, rows); + + png_write_png(png, info, 0, 0); + png_write_end(png, info); + png_destroy_write_struct(&png, &info); + + free(rows); + + img_destroy(&tmpimg); + return 0; +} + +static void read_func(png_struct *png, unsigned char *data, size_t len) +{ + struct img_io *io = (struct img_io*)png_get_io_ptr(png); + + if(io->read(data, len, io->uptr) == -1) { + longjmp(png_jmpbuf(png), 1); + } +} + +static void write_func(png_struct *png, unsigned char *data, size_t len) +{ + struct img_io *io = (struct img_io*)png_get_io_ptr(png); + + if(io->write(data, len, io->uptr) == -1) { + longjmp(png_jmpbuf(png), 1); + } +} + +static void flush_func(png_struct *png) +{ + /* XXX does it matter that we can't flush? */ +} + +static int png_type_to_fmt(int color_type, int channel_bits) +{ + /* only 8 and 16 bits per channel ar supported at the moment */ + if(channel_bits != 8 && channel_bits != 16) { + return -1; + } + + switch(color_type) { + case PNG_COLOR_TYPE_RGB: + return channel_bits == 16 ? IMG_FMT_RGBF : IMG_FMT_RGB24; + + case PNG_COLOR_TYPE_RGB_ALPHA: + return channel_bits == 16 ? IMG_FMT_RGBAF : IMG_FMT_RGBA32; + + case PNG_COLOR_TYPE_GRAY: + return channel_bits == 16 ? IMG_FMT_GREYF : IMG_FMT_GREY8; + + default: + break; + } + return -1; +} + +static int fmt_to_png_type(enum img_fmt fmt) +{ + switch(fmt) { + case IMG_FMT_GREY8: + return PNG_COLOR_TYPE_GRAY; + + case IMG_FMT_RGB24: + return PNG_COLOR_TYPE_RGB; + + case IMG_FMT_RGBA32: + return PNG_COLOR_TYPE_RGBA; + + default: + break; + } + return -1; +} diff --git a/libs/imago/src/fileppm.c b/libs/imago/src/fileppm.c new file mode 100644 index 0000000..772c362 --- /dev/null +++ b/libs/imago/src/fileppm.c @@ -0,0 +1,153 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010 John Tsiombikas + +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 . +*/ + +/* -- Portable Pixmap (PPM) module -- */ + +#include +#include "imago2.h" +#include "ftmodule.h" + +static int check(struct img_io *io); +static int read(struct img_pixmap *img, struct img_io *io); +static int write(struct img_pixmap *img, struct img_io *io); + +int img_register_ppm(void) +{ + static struct ftype_module mod = {".ppm", check, read, write}; + return img_register_module(&mod); +} + + +static int check(struct img_io *io) +{ + char id[2]; + int res = -1; + long pos = io->seek(0, SEEK_CUR, io->uptr); + + if(io->read(id, 2, io->uptr) < 2) { + io->seek(pos, SEEK_SET, io->uptr); + return -1; + } + + if(id[0] == 'P' && (id[1] == '6' || id[1] == '3')) { + res = 0; + } + io->seek(pos, SEEK_SET, io->uptr); + return res; +} + +static int iofgetc(struct img_io *io) +{ + char c; + return io->read(&c, 1, io->uptr) < 1 ? -1 : c; +} + +static char *iofgets(char *buf, int size, struct img_io *io) +{ + int c; + char *ptr = buf; + + while(--size > 0 && (c = iofgetc(io)) != -1) { + *ptr++ = c; + if(c == '\n') break; + } + *ptr = 0; + + return ptr == buf ? 0 : buf; +} + +/* TODO: implement P3 reading */ +static int read(struct img_pixmap *img, struct img_io *io) +{ + char buf[256]; + int xsz, ysz, maxval, got_hdrlines = 1; + + if(!iofgets(buf, sizeof buf, io)) { + return -1; + } + if(!(buf[0] == 'P' && (buf[1] == '6' || buf[1] == '3'))) { + return -1; + } + + while(got_hdrlines < 3 && iofgets(buf, sizeof buf, io)) { + if(buf[0] == '#') continue; + + switch(got_hdrlines) { + case 1: + if(sscanf(buf, "%d %d\n", &xsz, &ysz) < 2) { + return -1; + } + break; + + case 2: + if(sscanf(buf, "%d\n", &maxval) < 1) { + return -1; + } + default: + break; + } + got_hdrlines++; + } + + if(xsz < 1 || ysz < 1 || maxval != 255) { + return -1; + } + + if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGB24, 0) == -1) { + return -1; + } + + if(io->read(img->pixels, xsz * ysz * 3, io->uptr) < (unsigned int)(xsz * ysz * 3)) { + return -1; + } + return 0; +} + +static int write(struct img_pixmap *img, struct img_io *io) +{ + int sz; + char buf[256]; + struct img_pixmap tmpimg; + + img_init(&tmpimg); + + if(img->fmt != IMG_FMT_RGB24) { + if(img_copy(&tmpimg, img) == -1) { + return -1; + } + if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) { + return -1; + } + img = &tmpimg; + } + + sprintf(buf, "P6\n#written by libimago2\n%d %d\n255\n", img->width, img->height); + if(io->write(buf, strlen(buf), io->uptr) < strlen(buf)) { + img_destroy(&tmpimg); + return -1; + } + + sz = img->width * img->height * 3; + if(io->write(img->pixels, sz, io->uptr) < (unsigned int)sz) { + img_destroy(&tmpimg); + return -1; + } + + img_destroy(&tmpimg); + return 0; +} diff --git a/libs/imago/src/filergbe.c b/libs/imago/src/filergbe.c new file mode 100644 index 0000000..6ba6c4a --- /dev/null +++ b/libs/imago/src/filergbe.c @@ -0,0 +1,501 @@ +/* This file contains code to read and write four byte rgbe file format + * developed by Greg Ward. It handles the conversions between rgbe and + * pixels consisting of floats. The data is assumed to be an array of floats. + * By default there are three floats per pixel in the order red, green, blue. + * (RGBE_DATA_??? values control this.) + * + * written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95 + * based on code written by Greg Ward + * minor modifications by John Tsiombikas (nuclear@member.fsf.org) apr.9 2007 + */ + +#include +#include +#include +#include +#include +#include +#include "imago2.h" +#include "ftmodule.h" + + +typedef struct { + int valid; /* indicate which fields are valid */ + char programtype[16]; /* listed at beginning of file to identify it + * after "#?". defaults to "RGBE" */ + float gamma; /* image has already been gamma corrected with + * given gamma. defaults to 1.0 (no correction) */ + float exposure; /* a value of 1.0 in an image corresponds to + * watts/steradian/m^2. + * defaults to 1.0 */ +} rgbe_header_info; + + +static int check(struct img_io *io); +static int read(struct img_pixmap *img, struct img_io *io); +static int write(struct img_pixmap *img, struct img_io *io); + +static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info); +static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines); + + +int img_register_rgbe(void) +{ + static struct ftype_module mod = {".rgbe", check, read, write}; + return img_register_module(&mod); +} + + +static int check(struct img_io *io) +{ + int xsz, ysz, res; + long pos = io->seek(0, SEEK_CUR, io->uptr); + + rgbe_header_info hdr; + res = rgbe_read_header(io, &xsz, &ysz, &hdr); + + io->seek(pos, SEEK_SET, io->uptr); + return res; +} + +static int read(struct img_pixmap *img, struct img_io *io) +{ + int xsz, ysz; + rgbe_header_info hdr; + + if(rgbe_read_header(io, &xsz, &ysz, &hdr) == -1) { + return -1; + } + + if(img_set_pixels(img, xsz, ysz, IMG_FMT_RGBF, 0) == -1) { + return -1; + } + if(rgbe_read_pixels_rle(io, img->pixels, xsz, ysz) == -1) { + return -1; + } + return 0; +} + +static int write(struct img_pixmap *img, struct img_io *io) +{ + return -1; /* TODO */ +} + + +static int iofgetc(struct img_io *io) +{ + char c; + return io->read(&c, 1, io->uptr) < 1 ? -1 : c; +} + +static char *iofgets(char *buf, int size, struct img_io *io) +{ + int c; + char *ptr = buf; + + while(--size > 0 && (c = iofgetc(io)) != -1) { + *ptr++ = c; + if(c == '\n') break; + } + *ptr = 0; + + return ptr == buf ? 0 : buf; +} + + +/* flags indicating which fields in an rgbe_header_info are valid */ +#define RGBE_VALID_PROGRAMTYPE 0x01 +#define RGBE_VALID_GAMMA 0x02 +#define RGBE_VALID_EXPOSURE 0x04 + +/* return codes for rgbe routines */ +#define RGBE_RETURN_SUCCESS 0 +#define RGBE_RETURN_FAILURE -1 + + +#if defined(__cplusplus) || defined(GNUC) || __STDC_VERSION >= 199901L +#define INLINE inline +#else +#define INLINE +#endif + +/* offsets to red, green, and blue components in a data (float) pixel */ +#define RGBE_DATA_RED 0 +#define RGBE_DATA_GREEN 1 +#define RGBE_DATA_BLUE 2 + +/* number of floats per pixel */ +#define RGBE_DATA_SIZE 3 + +enum rgbe_error_codes { + rgbe_read_error, + rgbe_write_error, + rgbe_format_error, + rgbe_memory_error +}; + + +/* default error routine. change this to change error handling */ +static int rgbe_error(int rgbe_error_code, char *msg) +{ + switch (rgbe_error_code) { + case rgbe_read_error: + fprintf(stderr, "RGBE read error: %s\n", strerror(errno)); + break; + + case rgbe_write_error: + fprintf(stderr, "RGBE write error: %s\n", strerror(errno)); + break; + + case rgbe_format_error: + fprintf(stderr, "RGBE bad file format: %s\n", msg); + break; + + default: + case rgbe_memory_error: + fprintf(stderr, "RGBE error: %s\n", msg); + } + return RGBE_RETURN_FAILURE; +} + +/* standard conversion from float pixels to rgbe pixels */ +/*static INLINE void float2rgbe(unsigned char rgbe[4], float red, float green, float blue) +{ + float v; + int e; + + v = red; + if(green > v) + v = green; + if(blue > v) + v = blue; + if(v < 1e-32) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + v = frexp(v, &e) * 256.0 / v; + rgbe[0] = (unsigned char)(red * v); + rgbe[1] = (unsigned char)(green * v); + rgbe[2] = (unsigned char)(blue * v); + rgbe[3] = (unsigned char)(e + 128); + } +}*/ + +/* standard conversion from rgbe to float pixels */ +/* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */ +/* in the range [0,1] to map back into the range [0,1]. */ +static INLINE void rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4]) +{ + float f; + + if(rgbe[3]) { /*nonzero pixel */ + f = ldexp(1.0, rgbe[3] - (int)(128 + 8)); + *red = rgbe[0] * f; + *green = rgbe[1] * f; + *blue = rgbe[2] * f; + } else + *red = *green = *blue = 0.0; +} + +#if 0 +/* default minimal header. modify if you want more information in header */ +static int rgbe_write_header(FILE * fp, int width, int height, rgbe_header_info * info) +{ + char *programtype = "RGBE"; + + if(info && (info->valid & RGBE_VALID_PROGRAMTYPE)) + programtype = info->programtype; + if(fprintf(fp, "#?%s\n", programtype) < 0) + return rgbe_error(rgbe_write_error, NULL); + /* The #? is to identify file type, the programtype is optional. */ + if(info && (info->valid & RGBE_VALID_GAMMA)) { + if(fprintf(fp, "GAMMA=%g\n", info->gamma) < 0) + return rgbe_error(rgbe_write_error, NULL); + } + if(info && (info->valid & RGBE_VALID_EXPOSURE)) { + if(fprintf(fp, "EXPOSURE=%g\n", info->exposure) < 0) + return rgbe_error(rgbe_write_error, NULL); + } + if(fprintf(fp, "FORMAT=32-bit_rle_rgbe\n\n") < 0) + return rgbe_error(rgbe_write_error, NULL); + if(fprintf(fp, "-Y %d +X %d\n", height, width) < 0) + return rgbe_error(rgbe_write_error, NULL); + return RGBE_RETURN_SUCCESS; +} +#endif + +/* minimal header reading. modify if you want to parse more information */ +static int rgbe_read_header(struct img_io *io, int *width, int *height, rgbe_header_info * info) +{ + char buf[128]; + float tempf; + int i; + + if(info) { + info->valid = 0; + info->programtype[0] = 0; + info->gamma = info->exposure = 1.0; + } + if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == NULL) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ + if((buf[0] != '#') || (buf[1] != '?')) { + /* if you want to require the magic token then uncomment the next line */ + /*return rgbe_error(rgbe_format_error,"bad initial token"); */ + } else if(info) { + info->valid |= RGBE_VALID_PROGRAMTYPE; + for(i = 0; i < sizeof(info->programtype) - 1; i++) { + if((buf[i + 2] == 0) || isspace(buf[i + 2])) + break; + info->programtype[i] = buf[i + 2]; + } + info->programtype[i] = 0; + if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) + return rgbe_error(rgbe_read_error, NULL); + } + for(;;) { + if((buf[0] == 0) || (buf[0] == '\n')) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "no FORMAT specifier found");*/ + else if(strcmp(buf, "FORMAT=32-bit_rle_rgbe\n") == 0) + break; /* format found so break out of loop */ + else if(info && (sscanf(buf, "GAMMA=%g", &tempf) == 1)) { + info->gamma = tempf; + info->valid |= RGBE_VALID_GAMMA; + } else if(info && (sscanf(buf, "EXPOSURE=%g", &tempf) == 1)) { + info->exposure = tempf; + info->valid |= RGBE_VALID_EXPOSURE; + } + if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ + } + if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ + if(strcmp(buf, "\n") != 0) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing blank line after FORMAT specifier");*/ + if(iofgets(buf, sizeof(buf) / sizeof(buf[0]), io) == 0) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_read_error, NULL);*/ + if(sscanf(buf, "-Y %d +X %d", height, width) < 2) + return RGBE_RETURN_FAILURE;/*rgbe_error(rgbe_format_error, "missing image size specifier");*/ + return RGBE_RETURN_SUCCESS; +} + +#if 0 +/* simple write routine that does not use run length encoding */ + +/* These routines can be made faster by allocating a larger buffer and + fread-ing and fwrite-ing the data in larger chunks */ +static int rgbe_write_pixels(FILE * fp, float *data, int numpixels) +{ + unsigned char rgbe[4]; + + while(numpixels-- > 0) { + float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]); + data += RGBE_DATA_SIZE; + if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) + return rgbe_error(rgbe_write_error, NULL); + } + return RGBE_RETURN_SUCCESS; +} +#endif + +/* simple read routine. will not correctly handle run length encoding */ +static int rgbe_read_pixels(struct img_io *io, float *data, int numpixels) +{ + unsigned char rgbe[4]; + + while(numpixels-- > 0) { + if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) + return rgbe_error(rgbe_read_error, NULL); + rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe); + data += RGBE_DATA_SIZE; + } + return RGBE_RETURN_SUCCESS; +} + +#if 0 +/* The code below is only needed for the run-length encoded files. */ + +/* Run length encoding adds considerable complexity but does */ + +/* save some space. For each scanline, each channel (r,g,b,e) is */ + +/* encoded separately for better compression. */ + +static int rgbe_write_bytes_rle(struct img_io *io, unsigned char *data, int numbytes) +{ +#define MINRUNLENGTH 4 + int cur, beg_run, run_count, old_run_count, nonrun_count; + unsigned char buf[2]; + + cur = 0; + while(cur < numbytes) { + beg_run = cur; + /* find next run of length at least 4 if one exists */ + run_count = old_run_count = 0; + while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) { + beg_run += run_count; + old_run_count = run_count; + run_count = 1; + while((beg_run + run_count < numbytes) && (run_count < 127) + && (data[beg_run] == data[beg_run + run_count])) + run_count++; + } + /* if data before next big run is a short run then write it as such */ + if((old_run_count > 1) && (old_run_count == beg_run - cur)) { + buf[0] = 128 + old_run_count; /*write short run */ + buf[1] = data[cur]; + if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1) + return rgbe_error(rgbe_write_error, NULL); + cur = beg_run; + } + /* write out bytes until we reach the start of the next run */ + while(cur < beg_run) { + nonrun_count = beg_run - cur; + if(nonrun_count > 128) + nonrun_count = 128; + buf[0] = nonrun_count; + if(fwrite(buf, sizeof(buf[0]), 1, fp) < 1) + return rgbe_error(rgbe_write_error, NULL); + if(fwrite(&data[cur], sizeof(data[0]) * nonrun_count, 1, fp) < 1) + return rgbe_error(rgbe_write_error, NULL); + cur += nonrun_count; + } + /* write out next run if one was found */ + if(run_count >= MINRUNLENGTH) { + buf[0] = 128 + run_count; + buf[1] = data[beg_run]; + if(fwrite(buf, sizeof(buf[0]) * 2, 1, fp) < 1) + return rgbe_error(rgbe_write_error, NULL); + cur += run_count; + } + } + return RGBE_RETURN_SUCCESS; +#undef MINRUNLENGTH +} + +static int rgbe_write_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines) +{ + unsigned char rgbe[4]; + unsigned char *buffer; + int i, err; + + if((scanline_width < 8) || (scanline_width > 0x7fff)) + /* run length encoding is not allowed so write flat */ + return rgbe_write_pixels(io, data, scanline_width * num_scanlines); + buffer = (unsigned char *)malloc(sizeof(unsigned char) * 4 * scanline_width); + if(buffer == NULL) + /* no buffer space so write flat */ + return rgbe_write_pixels(fp, data, scanline_width * num_scanlines); + while(num_scanlines-- > 0) { + rgbe[0] = 2; + rgbe[1] = 2; + rgbe[2] = scanline_width >> 8; + rgbe[3] = scanline_width & 0xFF; + if(fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) { + free(buffer); + return rgbe_error(rgbe_write_error, NULL); + } + for(i = 0; i < scanline_width; i++) { + float2rgbe(rgbe, data[RGBE_DATA_RED], data[RGBE_DATA_GREEN], data[RGBE_DATA_BLUE]); + buffer[i] = rgbe[0]; + buffer[i + scanline_width] = rgbe[1]; + buffer[i + 2 * scanline_width] = rgbe[2]; + buffer[i + 3 * scanline_width] = rgbe[3]; + data += RGBE_DATA_SIZE; + } + /* write out each of the four channels separately run length encoded */ + /* first red, then green, then blue, then exponent */ + for(i = 0; i < 4; i++) { + if((err = rgbe_write_bytes_rle(fp, &buffer[i * scanline_width], + scanline_width)) != RGBE_RETURN_SUCCESS) { + free(buffer); + return err; + } + } + } + free(buffer); + return RGBE_RETURN_SUCCESS; +} +#endif + +static int rgbe_read_pixels_rle(struct img_io *io, float *data, int scanline_width, int num_scanlines) +{ + unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end; + int i, count; + unsigned char buf[2]; + + if((scanline_width < 8) || (scanline_width > 0x7fff)) + /* run length encoding is not allowed so read flat */ + return rgbe_read_pixels(io, data, scanline_width * num_scanlines); + scanline_buffer = NULL; + /* read in each successive scanline */ + while(num_scanlines > 0) { + if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) { + free(scanline_buffer); + return rgbe_error(rgbe_read_error, NULL); + } + if((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) { + /* this file is not run length encoded */ + rgbe2float(&data[0], &data[1], &data[2], rgbe); + data += RGBE_DATA_SIZE; + free(scanline_buffer); + return rgbe_read_pixels(io, data, scanline_width * num_scanlines - 1); + } + if((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) { + free(scanline_buffer); + return rgbe_error(rgbe_format_error, "wrong scanline width"); + } + if(scanline_buffer == NULL) + scanline_buffer = (unsigned char *) + malloc(sizeof(unsigned char) * 4 * scanline_width); + if(scanline_buffer == NULL) + return rgbe_error(rgbe_memory_error, "unable to allocate buffer space"); + + ptr = &scanline_buffer[0]; + /* read each of the four channels for the scanline into the buffer */ + for(i = 0; i < 4; i++) { + ptr_end = &scanline_buffer[(i + 1) * scanline_width]; + while(ptr < ptr_end) { + if(io->read(buf, sizeof(buf[0]) * 2, io->uptr) < 1) { + free(scanline_buffer); + return rgbe_error(rgbe_read_error, NULL); + } + if(buf[0] > 128) { + /* a run of the same value */ + count = buf[0] - 128; + if((count == 0) || (count > ptr_end - ptr)) { + free(scanline_buffer); + return rgbe_error(rgbe_format_error, "bad scanline data"); + } + while(count-- > 0) + *ptr++ = buf[1]; + } else { + /* a non-run */ + count = buf[0]; + if((count == 0) || (count > ptr_end - ptr)) { + free(scanline_buffer); + return rgbe_error(rgbe_format_error, "bad scanline data"); + } + *ptr++ = buf[1]; + if(--count > 0) { + if(io->read(ptr, sizeof(*ptr) * count, io->uptr) < 1) { + free(scanline_buffer); + return rgbe_error(rgbe_read_error, NULL); + } + ptr += count; + } + } + } + } + /* now convert data from buffer into floats */ + for(i = 0; i < scanline_width; i++) { + rgbe[0] = scanline_buffer[i]; + rgbe[1] = scanline_buffer[i + scanline_width]; + rgbe[2] = scanline_buffer[i + 2 * scanline_width]; + rgbe[3] = scanline_buffer[i + 3 * scanline_width]; + rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe); + data += RGBE_DATA_SIZE; + } + num_scanlines--; + } + free(scanline_buffer); + return RGBE_RETURN_SUCCESS; +} diff --git a/libs/imago/src/filetga.c b/libs/imago/src/filetga.c new file mode 100644 index 0000000..97504ca --- /dev/null +++ b/libs/imago/src/filetga.c @@ -0,0 +1,250 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010-2015 John Tsiombikas + +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 . +*/ + +/* -- Targa (tga) module -- */ + +#include +#include +#include "inttypes.h" +#include "imago2.h" +#include "ftmodule.h" + + +#if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \ + (defined(__alpha__) || defined(__alpha)) || \ + defined(__arm__) || \ + (defined(__mips__) && defined(__MIPSEL__)) || \ + defined(__SYMBIAN32__) || \ + defined(__x86_64__) || \ + defined(__LITTLE_ENDIAN__) +/* little endian */ +#define read_int16_le(f) read_int16(f) +#else +/* big endian */ +#define read_int16_le(f) read_int16_inv(f) +#endif /* endian check */ + + +enum { + IMG_NONE, + IMG_CMAP, + IMG_RGBA, + IMG_BW, + + IMG_RLE_CMAP = 9, + IMG_RLE_RGBA, + IMG_RLE_BW +}; + +#define IS_RLE(x) ((x) >= IMG_RLE_CMAP) +#define IS_RGBA(x) ((x) == IMG_RGBA || (x) == IMG_RLE_RGBA) + + +struct tga_header { + uint8_t idlen; /* id field length */ + uint8_t cmap_type; /* color map type (0:no color map, 1:color map present) */ + uint8_t img_type; /* image type: + * 0: no image data + * 1: uncomp. color-mapped 9: RLE color-mapped + * 2: uncomp. true color 10: RLE true color + * 3: uncomp. black/white 11: RLE black/white */ + uint16_t cmap_first; /* color map first entry index */ + uint16_t cmap_len; /* color map length */ + uint8_t cmap_entry_sz; /* color map entry size */ + uint16_t img_x; /* X-origin of the image */ + uint16_t img_y; /* Y-origin of the image */ + uint16_t img_width; /* image width */ + uint16_t img_height; /* image height */ + uint8_t img_bpp; /* bits per pixel */ + uint8_t img_desc; /* descriptor: + * bits 0 - 3: alpha or overlay bits + * bits 5 & 4: origin (0 = bottom/left, 1 = top/right) + * bits 7 & 6: data interleaving */ +}; + +struct tga_footer { + uint32_t ext_off; /* extension area offset */ + uint32_t devdir_off; /* developer directory offset */ + char sig[18]; /* signature with . and \0 */ +}; + + +static int check(struct img_io *io); +static int read(struct img_pixmap *img, struct img_io *io); +static int write(struct img_pixmap *img, struct img_io *io); +static int read_pixel(struct img_io *io, int rdalpha, uint32_t *pix); +static int16_t read_int16(struct img_io *io); +static int16_t read_int16_inv(struct img_io *io); + +int img_register_tga(void) +{ + static struct ftype_module mod = {".tga", check, read, write}; + return img_register_module(&mod); +} + + +static int check(struct img_io *io) +{ + struct tga_footer foot; + int res = -1; + long pos = io->seek(0, SEEK_CUR, io->uptr); + io->seek(-18, SEEK_END, io->uptr); + + if(io->read(foot.sig, 17, io->uptr) < 17) { + io->seek(pos, SEEK_SET, io->uptr); + return -1; + } + + if(memcmp(foot.sig, "TRUEVISION-XFILE.", 17) == 0) { + res = 0; + } + io->seek(pos, SEEK_SET, io->uptr); + return res; +} + +static int iofgetc(struct img_io *io) +{ + char c; + return io->read(&c, 1, io->uptr) < 1 ? -1 : c; +} + +static int read(struct img_pixmap *img, struct img_io *io) +{ + struct tga_header hdr; + int x, y; + int i, c; + uint32_t ppixel = 0; + int rle_mode = 0, rle_pix_left = 0; + int rdalpha; + + /* read header */ + hdr.idlen = iofgetc(io); + hdr.cmap_type = iofgetc(io); + hdr.img_type = iofgetc(io); + hdr.cmap_first = read_int16_le(io); + hdr.cmap_len = read_int16_le(io); + hdr.cmap_entry_sz = iofgetc(io); + hdr.img_x = read_int16_le(io); + hdr.img_y = read_int16_le(io); + hdr.img_width = read_int16_le(io); + hdr.img_height = read_int16_le(io); + hdr.img_bpp = iofgetc(io); + if((c = iofgetc(io)) == -1) { + return -1; + } + hdr.img_desc = c; + + if(!IS_RGBA(hdr.img_type)) { + fprintf(stderr, "only true color tga images supported\n"); + return -1; + } + + io->seek(hdr.idlen, SEEK_CUR, io); /* skip the image ID */ + + /* skip the color map if it exists */ + if(hdr.cmap_type == 1) { + io->seek(hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR, io); + } + + x = hdr.img_width; + y = hdr.img_height; + rdalpha = hdr.img_desc & 0xf; + + /* TODO make this IMG_FMT_RGB24 if there's no alpha channel */ + if(img_set_pixels(img, x, y, IMG_FMT_RGBA32, 0) == -1) { + return -1; + } + + for(i=0; ipixels + ((hdr.img_desc & 0x20) ? i : y - (i + 1)) * x; + + for(j=0; jread(&v, 2, io); + return v; +} + +static int16_t read_int16_inv(struct img_io *io) +{ + int16_t v; + io->read(&v, 2, io); + return ((v >> 8) & 0xff) | (v << 8); +} diff --git a/libs/imago/src/ftmodule.c b/libs/imago/src/ftmodule.c new file mode 100644 index 0000000..f0fc0f1 --- /dev/null +++ b/libs/imago/src/ftmodule.c @@ -0,0 +1,118 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010 John Tsiombikas + +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 . +*/ + +#include +#include +#include "ftmodule.h" + +static struct list_node { + struct ftype_module *module; + struct list_node *next; +} *modules; + +/* defined in modules.c which is generated by configure */ +void img_modules_init(); + +static int done_init; + +int img_register_module(struct ftype_module *mod) +{ + struct list_node *node; + + if(!(node = malloc(sizeof *node))) { + return -1; + } + + node->module = mod; + node->next = modules; + modules = node; + return 0; +} + +struct ftype_module *img_find_format_module(struct img_io *io) +{ + struct list_node *node; + + if(!done_init) { + img_modules_init(); + done_init = 1; + } + + node = modules; + while(node) { + if(node->module->check(io) != -1) { + return node->module; + } + node = node->next; + } + return 0; +} + +struct ftype_module *img_guess_format(const char *fname) +{ + struct list_node *node; + char *suffix; + int suffix_len; + + if(!done_init) { + img_modules_init(); + done_init = 1; + } + + if(!(suffix = strrchr(fname, '.'))) { + return 0; /* no suffix, can't guess ... */ + } + suffix_len = (int)strlen(suffix); + + node = modules; + while(node) { + char *suflist = node->module->suffix; + char *start, *end; + + while(*suflist) { + if(!(start = strstr(suflist, suffix))) { + break; + } + end = start + suffix_len; + + if(*end == ':' || *end == 0) { + return node->module; /* found it */ + } + suflist = end; + } + + node = node->next; + } + return 0; +} + +struct ftype_module *img_get_module(int idx) +{ + struct list_node *node; + + if(!done_init) { + img_modules_init(); + done_init = 1; + } + + node = modules; + while(node && idx--) { + node = node->next; + } + return node->module; +} diff --git a/libs/imago/src/ftmodule.h b/libs/imago/src/ftmodule.h new file mode 100644 index 0000000..7c3bd54 --- /dev/null +++ b/libs/imago/src/ftmodule.h @@ -0,0 +1,39 @@ +/* +libimago - a multi-format image file input/output library. +Copyright (C) 2010 John Tsiombikas + +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 . +*/ + +#ifndef FTYPE_MODULE_H_ +#define FTYPE_MODULE_H_ + +#include "imago2.h" + +struct ftype_module { + char *suffix; /* used for format autodetection during saving only */ + + int (*check)(struct img_io *io); + int (*read)(struct img_pixmap *img, struct img_io *io); + int (*write)(struct img_pixmap *img, struct img_io *io); +}; + +int img_register_module(struct ftype_module *mod); + +struct ftype_module *img_find_format_module(struct img_io *io); +struct ftype_module *img_guess_format(const char *fname); +struct ftype_module *img_get_module(int idx); + + +#endif /* FTYPE_MODULE_H_ */ diff --git a/libs/imago/src/ftype_module.c b/libs/imago/src/ftype_module.c deleted file mode 100644 index a3d3b04..0000000 --- a/libs/imago/src/ftype_module.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010 John Tsiombikas - -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 . -*/ - -#include -#include -#include "ftype_module.h" - -static struct list_node { - struct ftype_module *module; - struct list_node *next; -} *modules; - -/* defined in modules.c which is generated by configure */ -void img_modules_init(); - -static int done_init; - -int img_register_module(struct ftype_module *mod) -{ - struct list_node *node; - - if(!(node = malloc(sizeof *node))) { - return -1; - } - - node->module = mod; - node->next = modules; - modules = node; - return 0; -} - -struct ftype_module *img_find_format_module(struct img_io *io) -{ - struct list_node *node; - - if(!done_init) { - img_modules_init(); - done_init = 1; - } - - node = modules; - while(node) { - if(node->module->check(io) != -1) { - return node->module; - } - node = node->next; - } - return 0; -} - -struct ftype_module *img_guess_format(const char *fname) -{ - struct list_node *node; - char *suffix; - int suffix_len; - - if(!done_init) { - img_modules_init(); - done_init = 1; - } - - if(!(suffix = strrchr(fname, '.'))) { - return 0; /* no suffix, can't guess ... */ - } - suffix_len = (int)strlen(suffix); - - node = modules; - while(node) { - char *suflist = node->module->suffix; - char *start, *end; - - while(*suflist) { - if(!(start = strstr(suflist, suffix))) { - break; - } - end = start + suffix_len; - - if(*end == ':' || *end == 0) { - return node->module; /* found it */ - } - suflist = end; - } - - node = node->next; - } - return 0; -} - -struct ftype_module *img_get_module(int idx) -{ - struct list_node *node; - - if(!done_init) { - img_modules_init(); - done_init = 1; - } - - node = modules; - while(node && idx--) { - node = node->next; - } - return node->module; -} diff --git a/libs/imago/src/ftype_module.h b/libs/imago/src/ftype_module.h deleted file mode 100644 index 7c3bd54..0000000 --- a/libs/imago/src/ftype_module.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -libimago - a multi-format image file input/output library. -Copyright (C) 2010 John Tsiombikas - -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 . -*/ - -#ifndef FTYPE_MODULE_H_ -#define FTYPE_MODULE_H_ - -#include "imago2.h" - -struct ftype_module { - char *suffix; /* used for format autodetection during saving only */ - - int (*check)(struct img_io *io); - int (*read)(struct img_pixmap *img, struct img_io *io); - int (*write)(struct img_pixmap *img, struct img_io *io); -}; - -int img_register_module(struct ftype_module *mod); - -struct ftype_module *img_find_format_module(struct img_io *io); -struct ftype_module *img_guess_format(const char *fname); -struct ftype_module *img_get_module(int idx); - - -#endif /* FTYPE_MODULE_H_ */ diff --git a/libs/imago/src/imago2.c b/libs/imago/src/imago2.c index c90bc2a..30782dc 100644 --- a/libs/imago/src/imago2.c +++ b/libs/imago/src/imago2.c @@ -20,7 +20,7 @@ along with this program. If not, see . #include #include #include "imago2.h" -#include "ftype_module.h" +#include "ftmodule.h" static int pixel_size(enum img_fmt fmt); static size_t def_read(void *buf, size_t bytes, void *uptr); diff --git a/libs/imago/src/inttypes.h b/libs/imago/src/inttypes.h new file mode 100644 index 0000000..6f941ad --- /dev/null +++ b/libs/imago/src/inttypes.h @@ -0,0 +1,35 @@ +/* +colcycle - color cycling image viewer +Copyright (C) 2016 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef INT_TYPES_H_ +#define INT_TYPES_H_ + +#if defined(__DOS__) || defined(WIN32) +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +typedef unsigned long intptr_t; +#else +#include +#endif + +#endif /* INT_TYPES_H_ */ diff --git a/mklibs.bat b/mklibs.bat new file mode 100644 index 0000000..7a1ad1c --- /dev/null +++ b/mklibs.bat @@ -0,0 +1,3 @@ +cd libs\imago +wmake %1 %2 %3 %4 %5 %6 %7 %8 +cd ..\.. diff --git a/src/dos/keyb.h b/src/dos/keyb.h index 3007ac5..9be97db 100644 --- a/src/dos/keyb.h +++ b/src/dos/keyb.h @@ -62,6 +62,8 @@ void kb_wait(void); */ int kb_getkey(void); +void kb_putback(int key); + #ifdef __cplusplus } #endif diff --git a/src/tunnel.c b/src/tunnel.c index 4fbc16b..13eea70 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include "imago2.h" -- 1.7.10.4