diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 23 | ||||
| -rw-r--r-- | README | 50 | ||||
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | config.mk | 6 | ||||
| -rw-r--r-- | liblss16.7 | 62 | ||||
| -rw-r--r-- | liblss16.h | 44 | ||||
| -rw-r--r-- | liblss16_decode_strerror.3 | 43 | ||||
| -rw-r--r-- | liblss16_decode_strerror.c | 2 | ||||
| -rw-r--r-- | liblss16_decode_to_colour_index.3 | 221 | ||||
| -rw-r--r-- | liblss16_decode_to_colour_index.c | 8 | ||||
| -rw-r--r-- | liblss16_decoder_init.3 | 41 | ||||
| -rw-r--r-- | liblss16_encode_from_colour_index.3 | 108 | ||||
| -rw-r--r-- | liblss16_encode_from_colour_index.c | 16 | ||||
| -rw-r--r-- | liblss16_encode_strerror.3 | 43 | ||||
| -rw-r--r-- | liblss16_encode_strerror.c | 5 | ||||
| -rw-r--r-- | liblss16_encoder_init.3 | 125 | ||||
| -rw-r--r-- | liblss16_encoder_init.c | 4 | ||||
| -rw-r--r-- | liblss16_optimise.3 | 81 | ||||
| -rw-r--r-- | liblss16_optimise.c | 8 | ||||
| -rw-r--r-- | lss16.5 | 61 | ||||
| -rw-r--r-- | lss16toppm.1 | 98 | ||||
| -rw-r--r-- | lss16toppm.c | 9 | ||||
| -rw-r--r-- | mk/dynamic.mk | 2 | ||||
| -rw-r--r-- | mk/static.mk | 2 | ||||
| -rw-r--r-- | ppmtolss16.1 | 93 | 
26 files changed, 1112 insertions, 47 deletions
| @@ -13,3 +13,4 @@  *.gcno  *.gcda  /lss16toppm +/ppmtolss16 @@ -37,19 +37,26 @@ HDR =\  LOBJ = $(OBJ_LIB:.o=.lo) +MAN1 = $(BIN:=.1) +MAN3 = $(OBJ_LIB:.o=.3) +MAN5 = lss16.5 +MAN7 = liblss16.7 +  all: liblss16.a liblss16.$(LIBEXT) $(BIN)  $(OBJ): $(HDR)  $(LOBJ): $(HDR) +include mk/$(LINKING).mk +  .c.o:  	$(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS)  .c.lo:  	$(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) -lss16toppm: lss16toppm.o liblss16.a -	$(CC) -o $@ lss16toppm.o liblss16.a $(LDFLAGS) +lss16toppm: lss16toppm.o $(BIN_DEP) +	$(CC) -o $@ $@.o $(LDFLAGS) $(BIN_LDFLAGS)  liblss16.a: $(OBJ_LIB)  	@rm -f -- $@ @@ -70,6 +77,14 @@ install: liblss16.a liblss16.$(LIBEXT)  	ln -sf -- liblss16.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/liblss16.$(LIBMAJOREXT)"  	ln -sf -- liblss16.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/liblss16.$(LIBEXT)"  	cp -- liblss16.h "$(DESTDIR)$(PREFIX)/include/" +	mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man1" +	mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man3" +	mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man5" +	mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man7" +	cp -- $(MAN1) "$(DESTDIR)$(MANPREFIX)/man1/" +	cp -- $(MAN3) "$(DESTDIR)$(MANPREFIX)/man3/" +	cp -- $(MAN5) "$(DESTDIR)$(MANPREFIX)/man5/" +	cp -- $(MAN7) "$(DESTDIR)$(MANPREFIX)/man7/"  uninstall:  	-cd -- "$(DESTDIR)$(PREFIX)/bin/" && rm -f -- $(BIN) @@ -78,6 +93,10 @@ uninstall:  	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/liblss16.$(LIBMINOREXT)"  	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/liblss16.$(LIBEXT)"  	-rm -f -- "$(DESTDIR)$(PREFIX)/include/liblss16.h" +	-cd -- "$(DESTDIR)$(MANPREFIX)/man1/" && rm -f -- $(MAN1) +	-cd -- "$(DESTDIR)$(MANPREFIX)/man3/" && rm -f -- $(MAN3) +	-cd -- "$(DESTDIR)$(MANPREFIX)/man5/" && rm -f -- $(MAN5) +	-cd -- "$(DESTDIR)$(MANPREFIX)/man7/" && rm -f -- $(MAN7)  clean:  	-rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib @@ -0,0 +1,50 @@ +NAME +	liblss16 - Library for the SYSLINUX "ad hoc" LSS16 image format + +DESCRIPTION +	liblss16 is a C library for encoding and decode the LSS16 image file +	format, which is a SYSLINUX "ad hoc" lossless, compressed, low-fidelity +	image file format optimised bootloaders in low-end graphics +	environments. + +	liblss16 provides the following functions for decoding LSS16 images: + +		liblss16_decoder_init(3) +			Prepare state for liblss16_decode_to_colour_index(3). + +		liblss16_decode_to_colour_index(3) +			Decode an file. The colour of each pixel is output with +			the index of the colour in the colour palette. + +		liblss16_decode_strerror(3) +			Get error description for error code returned by +			liblss16_decode_to_colour_index(3). + +	liblss16 provides the following functions for encoding LSS16 images: + +		liblss16_optimise(3) +			Optimise an image for optimal compression with LSS16. + +		liblss16_encoder_init(3) +			Prepare state for liblss16_encode_from_colour_index(3). + +		liblss16_encode_from_colour_index(3) +			Encode an file. The colour of each pixle is input as the +			index of the colour in the colour palette. + +		liblss16_encode_strerror(3) +			Get error description for error code returned by +			liblss16_encoder_init(3) or +			liblss16_encode_from_colour_index(3). + +EXTENDED DESCRIPTION +	The liblss16 project also implements the following utilities: + +	lss16toppm(1) +		Convert an LSS16 file to a Portable Pixmap (PPM) file. + +	ppmtolss16(1) +		Convert a Portable Anymap (PNM) file to an LSS16 file. + +SEE ALSO +	lss16(5), syslinux(1) @@ -1,3 +0,0 @@ -Write ppmtolss16 -Write man pages -Write README @@ -3,6 +3,10 @@ MANPREFIX = $(PREFIX)/share/man  CC = c99 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -DHARDEN  CFLAGS   =  LDFLAGS  = + +LINKING = dynamic +# dynamic: dynamically link included utilities +# static:  statically link included utilities diff --git a/liblss16.7 b/liblss16.7 new file mode 100644 index 0000000..10c063c --- /dev/null +++ b/liblss16.7 @@ -0,0 +1,62 @@ +.TH LIBLSS16 7 LIBLSS16 +.SH NAME +liblss16 \- Library for the SYSLINUX \(dqad hoc\(dq LSS16 image format + +.SH DESCRIPTION +.B liblss16 +is a C library for encoding and decode the LSS16 image file +format, which is a SYSLINUX \(dqad hoc\(dq lossless, compressed, +low-fidelity image file format optimised bootloaders in low-end +graphics environments. +.PP +.B liblss16 +provides the following functions for decoding LSS16 images: +.RS +.TP +.BR liblss16_decoder_init (3) +Prepare state for +.BR liblss16_decode_to_colour_index (3). +.TP +.BR liblss16_decode_to_colour_index (3) +Decode an file. The colour of each pixel is output with +the index of the colour in the colour palette. +.TP +.BR liblss16_decode_strerror (3) +Get error description for error code returned by +.BR liblss16_decode_to_colour_index (3). +.RE +.PP +.B liblss16 +provides the following functions for encoding LSS16 images: +.RS +.TP +.BR liblss16_optimise (3) +Optimise an image for optimal compression with LSS16. +.TP +.BR liblss16_encoder_init (3) +Prepare state for +.BR liblss16_encode_from_colour_index (3). +.TP +.BR liblss16_encode_from_colour_index (3) +Encode an file. The colour of each pixle is input as +the index of the colour in the colour palette. +.TP +.BR liblss16_encode_strerror (3) +Get error description for error code returned by +.BR liblss16_encoder_init (3). +.RE + +.SH EXTENDED DESCRIPTION +The +.B liblss16 +project also implements the following utilities: +.TP +.BR lss16toppm (1) +Convert an LSS16 file to a Portable Pixmap (PPM) file. +.TP +.BR ppmtolss16 (1) +Convert a Portable Pixmap (PPM) file to an LSS16 file. + +.SH SEE ALSO +.BR lss16 (5), +.BR syslinux (1) @@ -6,6 +6,12 @@  #include <stdint.h> +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +#endif + +  /**   * Image decoding state   */ @@ -115,12 +121,7 @@ enum liblss16_encode_state {  	/**  	 * Encodig done  	 */ -	LIBLSS16_ENCODE_DONE, - -	/** -	 * Error occured while encoding -	 */ -	LIBLSS16_ENCODE_ERROR +	LIBLSS16_ENCODE_DONE  }; @@ -139,12 +140,7 @@ enum liblss16_encode_error {  	 * 6 bits, however at least one colour value  	 * had at least one of it it high bits set  	 */ -	LIBLSS16_ENCODE_BAD_COLOUR, - -	/** -	 * Colour index above 15 specified for a pixel -	 */ -	LIBLSS16_ENCODE_BAD_COLOUR_INDEX +	LIBLSS16_ENCODE_BAD_COLOUR  }; @@ -270,10 +266,9 @@ void liblss16_decoder_init(struct liblss16_decoder *decoder);   * is set to `LIBLSS16_DECODE_BAD_HEADER`   */  enum liblss16_decode_state liblss16_decode_to_colour_index( -	struct liblss16_decoder *decoder, -	const void *data, size_t length, size_t *consumed_out, -	uint8_t *pixels, size_t pixels_size, size_t *npixels_out, -	enum liblss16_decode_error *error_out); +	struct liblss16_decoder *decoder, const void *data, size_t length, +	size_t *consumed_out, uint8_t *pixels, size_t pixels_size, +	size_t *npixels_out, enum liblss16_decode_error *error_out);  /** @@ -319,16 +314,13 @@ int liblss16_encoder_init(struct liblss16_encoder *encoder, const struct liblss1   * @param   npixels        The number of provided pixels   * @param   nconsumed_out  Output parameter for the number of pixels consumed into   *                         to state of the encoder - * @param   error_out      Output parameter for the error; only set if - *                         `LIBLSS16_ENCODE_ERROR` is returned; may be `NULL`   * @return                 The processing state: normally `LIBLSS16_ENCODE_RUNNING`, - *                         but `LIBLSS16_ENCODE_DONE` when the image has been - *                         fully encoded, and `LIBLSS16_ENCODE_ERROR` on error + *                         but `LIBLSS16_ENCODE_DONE` when the image has been fully + *                         encoded   */  enum liblss16_encode_state liblss16_encode_from_colour_index( -	struct liblss16_encoder *encoder, void *buffer, size_t size, -	size_t *written_out, const uint8_t *pixels, size_t npixels, -	size_t *nconsumed_out, enum liblss16_encode_error *error_out); +	struct liblss16_encoder *encoder, void *buffer, size_t size, size_t *written_out, +	const uint8_t *pixels, size_t npixels, size_t *nconsumed_out);  /** @@ -347,7 +339,7 @@ const char *liblss16_encode_strerror(enum liblss16_encode_error error);   * Optimise and image   *    * @param  header  The image metadata - * @param  pixel   Buffer with pixels; the pixels are to encoded with the + * @param  pixels  Buffer with pixels; the pixels are to encoded with the   *                 colour index of each pixel. Pixels are encoded primarily   *                 from to the top down and secondarily from left to right.   *  @@ -357,4 +349,8 @@ const char *liblss16_encode_strerror(enum liblss16_encode_error error);  void liblss16_optimise(struct liblss16_header *header, uint8_t *pixels); +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +  #endif diff --git a/liblss16_decode_strerror.3 b/liblss16_decode_strerror.3 new file mode 100644 index 0000000..ee011ed --- /dev/null +++ b/liblss16_decode_strerror.3 @@ -0,0 +1,43 @@ +.TH LIBLSS16_DECODE_STRERROR 3 LIBLSS16 +.SH NAME +liblss16_decode_strerror \- Get error description for an LSS16 decoding error + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +enum liblss16_decode_error { /* values omitted */ }; + +const char *liblss16_decode_strerror(enum liblss16_decode_error \fIerror\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_decode_strerror () +function returns a stirng the describes +.IR error . +.PP +The function is used for decoding errors, which may be +received from the +.BR liblss16_decode_to_colour_index (3) +function. + +.SH RETURN VALUE +The +.BR liblss16_decode_strerror () +function returns a statically allocated single-line +of text (not LF-terminated) describing the error, in +sentence case, single-sentence (not period-terminated). +If the error code is not recognised, a generic text +is returned. + +.SH ERRORS +The +.BR liblss16_decode_strerror () +function cannot fail. + +.SH SEE ALSO +.BR liblss16 (7) diff --git a/liblss16_decode_strerror.c b/liblss16_decode_strerror.c index 3bd3c5a..cf2d8aa 100644 --- a/liblss16_decode_strerror.c +++ b/liblss16_decode_strerror.c @@ -5,7 +5,7 @@  const char *  liblss16_decode_strerror(enum liblss16_decode_error error)  { -	switch (error) { +	switch ((int)error) {  	case LIBLSS16_DECODE_TRUNCATED_MAGIC:  		return "Short file: magic number truncated"; diff --git a/liblss16_decode_to_colour_index.3 b/liblss16_decode_to_colour_index.3 new file mode 100644 index 0000000..797c4f5 --- /dev/null +++ b/liblss16_decode_to_colour_index.3 @@ -0,0 +1,221 @@ +.TH LIBLSS16_DECODE_TO_COLOUR_INDEX 3 LIBLSS16 +.SH NAME +liblss16_decode_to_colour_index \- Decode an LSS16 image file + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +enum liblss16_decode_state { +	LIBLSS16_DECODE_RUNNING, +	LIBLSS16_DECODE_END_OF_IMAGE, +	LIBLSS16_DECODE_ERROR +}; + +enum liblss16_decode_error { +	LIBLSS16_DECODE_TRUNCATED_MAGIC, +	LIBLSS16_DECODE_BAD_MAGIC, +	LIBLSS16_DECODE_TRUNCATED_HEADER, +	LIBLSS16_DECODE_BAD_IMAGE_SIZE, +	LIBLSS16_DECODE_BAD_COLOUR, +	LIBLSS16_DECODE_BAD_ROW_PADDING, +	LIBLSS16_DECODE_EXCESSIVE_RUN_LENGTH, +	LIBLSS16_DECODE_TRUNCATED_IMAGE +}; + +struct liblss16_colour { +	uint8_t \fIr\fP; +	uint8_t \fIg\fP; +	uint8_t \fIb\fP; +}; + +struct liblss16_header { +	uint16_t \fIwidth\fP; +	uint16_t \fIheight\fP; +	struct liblss16_colour \fIcolour_map\fP[16]; +}; + +struct liblss16_decoder { +	struct liblss16_header \fIimage\fP; +	/* internal fields omitted */ +}; + +enum liblss16_decode_state liblss16_decode_to_colour_index( +	struct liblss16_decoder *\fIdecoder\fP, +	const void *\fIdata\fP, size_t \fIlength\fP, size_t *\fIconsumed_out\fP, +	uint8_t *\fIpixels\fP, size_t \fIpixels_size\fP, size_t *\fInpixels_out\fP, +	enum liblss16_decode_error *\fIerror_out\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_decode_to_colour_index () +function decodes an image encoded in the LSS16 file format. +Before the decoding of a file is started +.I decoder +must be initialised with the +.BR liblss16_decoder_init (3) +function. The function is then repeatedly while it returns +.IR LIBLSS16_DECODE_RUNNING . +.PP +For each call, currently available file content is input in the +.I data +parameter, and the number of available bytes is input in the +.I length +parameter. After each call, the application shall discard the +.I *consumed_out +first bytes of +.I data +and decrease +.I length +by the same amount, but it may also append newly available +data, and increase +.I length +correspondingly. +.PP +The call shall provide a buffer for at least one pixel in the +.I pixels +parameter, and specify the number of pixels the buffer can +store in the +.I pixels_size +parameter. The function will set +.I *npixels_out +to the number of pixels output to the beginning of +.IR pixels . +Each pixel is encoded with a colour index, which is a non-negative +integer 15 or less. The function will set +.I decoder->image +the first time it sets +.I *npixels_out +to a non-zero value, or earlier. At this time, the width or height +of the image, in number of pixels, can be looked up in +.I decoder->image.width +and +.I decoder->image.height +respectively. Additionally the colour palette is also set, so the +colours of the returned pixels can be looked up. If the value +.I P +is returned for a pixel, +.I decoder->image.colour_map[P] +is a +.B struct liblss16_colour +that describes the pixel's colour; +.I .r +is an unsigned 8-bit integer value for the red component +of the pixel's sRGB colour, likewise +.I .g +is the green value and +.I .b +is the blue value. +.PP +.I decoder +must not be +.IR NULL . +.PP +.I data +may only be +.I NULL +if +.I length +is 0, which is used while still decoding +after then end of the file has been reached. +.PP +.I consumed_out +must not be +.IR NULL . +.PP +.I pixels +must not be null +.IR NULL , +and +.I pixels_size +must not be 0. +.PP +.I npixels_out +must not be +.IR NULL . +.PP +.I error_out +shall either be +.I NULL +or a pointer to where the error code shall be +stored should the function fail. + +.SH RETURN VALUE +The +.BR liblss16_decode_to_colour_index () +function will returns the following values: +.TP +.B LIBLSS16_DECODE_RUNNING +The end of the image has not yet been reached. +The file if truncated if the end of the file is reached. +.TP +.B LIBLSS16_DECODE_END_OF_IMAGE +The end of the image is reched. +If the end of the file has not yet been reached, it +contains extraneous data. +.TP +.B LIBLSS16_DECODE_ERROR +A decoding error has occured, and processing most be +aborted. This always indicate that the file is corrupted +or not an LSS16 file. +.I *error_out +will be se to indicate the error unless +.I error_out +is +.IR NULL . +.PP +Note that +.I *npixels_out +and +.I *consumed_out +are always set. + +.SH ERRORS +The +.BR liblss16_decode_to_colour_index () +function fails for the following reasons: +.TP +.B LIBLSS16_DECODE_TRUNCATED_MAGIC +The file contains up to the first three bytes of the +LSS16 magic number, but is truncated and does not +contain the fourth byte. +.TP +.B LIBLSS16_DECODE_BAD_MAGIC +The file does not begin with the LSS16 magic number. +.TP +.B LIBLSS16_DECODE_TRUNCATED_HEADER +The file is too short to contain the full header. +.TP +.B LIBLSS16_DECODE_BAD_IMAGE_SIZE +The image width is 0, the image height is 0, or +the image height exceeds 32767. + +.I decoder->image.width +and +.I decoder->image.height +will be set so each of the reasons apply can be +determined. +.TP +.B LIBLSS16_DECODE_BAD_COLOUR +The file is corrupt and the colour palette contains +a value greater than 63. +.TP +.B LIBLSS16_DECODE_BAD_ROW_PADDING +The file is corrupt and contains non-zero row padding. +.TP +.B LIBLSS16_DECODE_EXCESSIVE_RUN_LENGTH +The file is corrupt and contains a run length +crossing two or more rows of pixels. +.TP +.B LIBLSS16_DECODE_TRUNCATED_IMAGE +The file contains the full header, but is truncated +and does not contain the full image data. + +.SH SEE ALSO +.BR liblss16_decode_strerror (3), +.BR liblss16_encode_from_colour_index (3), +.BR liblss16 (7) diff --git a/liblss16_decode_to_colour_index.c b/liblss16_decode_to_colour_index.c index a552289..e1845e9 100644 --- a/liblss16_decode_to_colour_index.c +++ b/liblss16_decode_to_colour_index.c @@ -2,6 +2,11 @@  #include "liblss16.h"  #include <string.h> +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wimplicit-fallthrough" +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif +  enum liblss16_decode_state  liblss16_decode_to_colour_index(struct liblss16_decoder *decoder, @@ -210,11 +215,10 @@ liblss16_decode_to_colour_index(struct liblss16_decoder *decoder,  			} else if (decoder->internal.state == 2U) {  				decoder->internal.state = (uint8_t)(n | 128U);  			} else { -				m = (uint16_t)((n << 4) + (decoder->internal.state & 15U) + 16U); +				m = (uint16_t)((unsigned)(n << 4) + (decoder->internal.state & 15U) + 16U);  				goto put_m_pixels;  			}  		} -		break;  	}  	return LIBLSS16_DECODE_RUNNING; diff --git a/liblss16_decoder_init.3 b/liblss16_decoder_init.3 new file mode 100644 index 0000000..262fc07 --- /dev/null +++ b/liblss16_decoder_init.3 @@ -0,0 +1,41 @@ +.TH LIBLSS16_DECODER_INIT 3 LIBLSS16 +.SH NAME +liblss16_decoder_init \- Prepare state for decoding LSS16 image file + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +struct liblss16_decoder { /* fields omitted */ }; + +void liblss16_decoder_init(struct liblss16_decoder *\fIdecoder\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_decoder_init () +function initialises +.I *decoder +for the first call to the +.BR liblss16_decode_to_colour_index (3) +function. +.PP +.I decoder +must not be +.IR NULL . +.PP +There is no corresponding deallocator as no dynamic resources are allocated. + +.SH RETURN VALUE +None. + +.SH ERRORS +The +.BR liblss16_decoder_init () +function cannot fail. + +.SH SEE ALSO +.BR liblss16 (7) diff --git a/liblss16_encode_from_colour_index.3 b/liblss16_encode_from_colour_index.3 new file mode 100644 index 0000000..9a55c09 --- /dev/null +++ b/liblss16_encode_from_colour_index.3 @@ -0,0 +1,108 @@ +.TH LIBLSS16_ENCODE_FROM_COLOUR_INDEX 3 LIBLSS16 +.SH NAME +liblss16_encode_from_colour_index \- Encode an LSS16 image file + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +enum liblss16_encode_state { +	LIBLSS16_ENCODE_RUNNING, +	LIBLSS16_ENCODE_DONE +}; + +struct liblss16_encoder { /* fields omitted */ }; + +enum liblss16_encode_state liblss16_encode_from_colour_index( +	struct liblss16_encoder *\fIencoder\fP, void *\fIbuffer\fP, size_t \fIsize\fP, +	size_t *\fIwritten_out\fP, const uint8_t *\fIpixels\fP, size_t \fInpixels\fP, +	size_t *\fInconsumed_out\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_encode_from_colour_index () +function encodes an image as in LSS16 file. +Before beginning the encoding, the application +must first initalise +.I encoder +with its initial state and image meta data +using the +.BR liblss16_encoder_init (3) +function. After than, the +.BR liblss16_encode_from_colour_index () +function is called repeatedly until it returns +.BR LIBLSS16_ENCODE_DONE . +.PP +The application shall provide an array of pixels +in the +.I pixels +parameter, with the number of provided pixels +specified in the +.I npixels +parameter. After each call, the application shall +discard the first +.I *nconsumed_out +pixels but may append additional pixels. +.I npixels +shall be decreased by +.I *nconsumed_out +and increased by the number of new pixels. +The application shall also provide a file content +output buffer in the +.I buffer +parameter and the size, in bytes, of the buffer +in the +.I size +parameter. After each call, the application shall +shall write the first +.I *written_out +bytes from +.I buffer +to the output file. +.PP +.IR encoder , +.IR buffer , +.IR written_out , +and +.IR nconsumed_out +must not be +.IR NULL , +and +.I size +must be at least 1. +.PP +.I pixels +may only be +.I NULL +if +.I npixels +is 0. + +.SH RETURN VALUE +The +.BR liblss16_encode_from_colour_index () +function returns +.B LIBLSS16_ENCODE_RUNNING +until the last byte for the LSS16 file +hsa been written. Once the last byte +has been written, it returns +.BR LIBLSS16_ENCODE_DONE . +Note that +.I *written_out +and +.I *nconsumed_out +are always set. + +.SH ERRORS +The +.BR liblss16_encode_from_colour_index () +function cannot fail. + +.SH SEE ALSO +.BR liblss16_encode_strerror (3), +.BR liblss16_decode_to_colour_index (3), +.BR liblss16 (7) diff --git a/liblss16_encode_from_colour_index.c b/liblss16_encode_from_colour_index.c index 1efff36..95b600b 100644 --- a/liblss16_encode_from_colour_index.c +++ b/liblss16_encode_from_colour_index.c @@ -1,7 +1,12 @@  /* See LICENSE file for copyright and license details. */  #include "liblss16.h" -#include <string.h>  #include <stdlib.h> +#include <string.h> + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wimplicit-fallthrough" +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif  static size_t @@ -16,9 +21,8 @@ flush_buffer(struct liblss16_encoder *encoder, uint8_t *buffer, size_t size)  enum liblss16_encode_state -liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer_, size_t size, -                                  size_t *written_out, const uint8_t *pixels, size_t npixels, -                                  size_t *nconsumed_out, enum liblss16_encode_error *error_out) +liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer_, size_t size, size_t *written_out, +                                  const uint8_t *pixels, size_t npixels, size_t *nconsumed_out)  {  	uint8_t *buffer = buffer_;  	size_t n; @@ -120,10 +124,6 @@ liblss16_encode_from_colour_index(struct liblss16_encoder *encoder, void *buffer  	while (npixels--) {  		if (*pixels == encoder->previous) {  			encoder->repetition++; -		} else if (*pixels > 15U) { -			if (error_out) -				*error_out = LIBLSS16_ENCODE_BAD_COLOUR_INDEX; -			return LIBLSS16_ENCODE_ERROR;  		} else {  			if (!encoder->repetition) {  				/* do nothing */ diff --git a/liblss16_encode_strerror.3 b/liblss16_encode_strerror.3 new file mode 100644 index 0000000..758c887 --- /dev/null +++ b/liblss16_encode_strerror.3 @@ -0,0 +1,43 @@ +.TH LIBLSS16_ENCODE_STRERROR 3 LIBLSS16 +.SH NAME +liblss16_encode_strerror \- Get error description for an LSS16 encoding error + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +enum liblss16_encode_error { /* values omitted */ }; + +const char *liblss16_encode_strerror(enum liblss16_encode_error \fIerror\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_encode_strerror () +function returns a stirng the describes +.IR error . +.PP +The function is used for encoding errors, which may be +received from the +.BR liblss16_encoder_init (3) +function. + +.SH RETURN VALUE +The +.BR liblss16_encode_strerror () +function returns a statically allocated single-line +of text (not LF-terminated) describing the error, in +sentence case, single-sentence (not period-terminated). +If the error code is not recognised, a generic text +is returned. + +.SH ERRORS +The +.BR liblss16_encode_strerror () +function cannot fail. + +.SH SEE ALSO +.BR liblss16 (7) diff --git a/liblss16_encode_strerror.c b/liblss16_encode_strerror.c index a5fcd49..e4d1ab9 100644 --- a/liblss16_encode_strerror.c +++ b/liblss16_encode_strerror.c @@ -5,16 +5,13 @@  const char *  liblss16_encode_strerror(enum liblss16_encode_error error)  { -	switch (error) { +	switch ((int)error) {  	case LIBLSS16_ENCODE_BAD_IMAGE_SIZE:  		return "Unencodable image: unsupported image size";  	case LIBLSS16_ENCODE_BAD_COLOUR:  		return "Invalid colour map: 6-bit colours encoded with additional bits"; -	case LIBLSS16_ENCODE_BAD_COLOUR_INDEX: -		return "Invalid image: colour index out of range"; -  	default:  		return "Unrecognised error";  	} diff --git a/liblss16_encoder_init.3 b/liblss16_encoder_init.3 new file mode 100644 index 0000000..b5f37f9 --- /dev/null +++ b/liblss16_encoder_init.3 @@ -0,0 +1,125 @@ +.TH LIBLSS16_ENCODER_INIT 3 LIBLSS16 +.SH NAME +liblss16_encoder_init \- Prepare state for encoding LSS16 image file + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +enum liblss16_encode_error { +	LIBLSS16_ENCODE_BAD_IMAGE_SIZE, +	LIBLSS16_ENCODE_BAD_COLOUR +}; + +struct liblss16_colour { +	uint8_t \fIr\fP; +	uint8_t \fIg\fP; +	uint8_t \fIb\fP; +}; + +struct liblss16_header { +	uint16_t \fIwidth\fP; +	uint16_t \fIheight\fP; +	struct liblss16_colour \fIcolour_map\fP[16]; +}; + +struct liblss16_encoder { /* fields omitted */ }; + +int liblss16_encoder_init(struct liblss16_encoder *\fIencoder\fP, +                          const struct liblss16_header *\fIheader\fP, int \fIrgb6\fP, +                          enum liblss16_encode_error *\fIerror_out\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_encoder_init () +function initialises +.I *encoder +for the first call to the +.BR liblss16_encode_from_colour_index (3) +function. +.PP +.I header->width +shall be the width, in pixels, of the image. +.PP +.I header->height +shall be the height, in pixels, of the image. +.PP +.I header->colour_map +shall be the image's colour palette. Each +.B struct liblss16_colour +is encoded in sRGB with either 6 bits per channel +or 8 bits per channel +.RI ( .r +for the red channel, +.I .g +for the green channel, and +.I .b +for the blue channel). +.PP +If +.I rgb6 +is zero, each +.B struct liblss16_colour is encoded with 8 bits +per channel, and scaled down to 6 bits by the +function (the scaled down value will be stored in +.I *header +and output when ending the file). +.PP +If +.I rgb6 +is non-zero, each +.B struct liblss16_colour is encoded with 6 bits +per channel, and the function will validate that +the 2 highest bits in each value is cleared. +.PP +.I error_out +shall either be +.I NULL +or a pointer to where the error code shall be +stored should the function fail. +.PP +Before calling the +.BR liblss16_encoder_init () +function, the application may choose to call the +.BR liblss16_optimise (3) +function. + +.SH RETURN VALUE +The +.BR liblss16_encoder_init () +function returns 0 upon successful +completion. On failure, returns -1 +and sets +.I *error_out +(unless +.I error_out +is +.IR NULL ) +to indicate the error. + +.SH ERRORS +The +.BR liblss16_encoder_init () +function will fail for the following reasons: +.TP +.B LIBLSS16_ENCODE_BAD_IMAGE_SIZE +The image width was 0. +.TP +.B LIBLSS16_ENCODE_BAD_IMAGE_SIZE +The image height was 0. +.TP +.B LIBLSS16_ENCODE_BAD_IMAGE_SIZE +The image height was greater than 32767. +.TP +.B LIBLSS16_ENCODE_BAD_COLOUR +.I rgb6 +was non-zero, and one of the colour values +was create than 63. + +.SH SEE ALSO +.BR liblss16_encode_strerror (3), +.BR liblss16 (7) diff --git a/liblss16_encoder_init.c b/liblss16_encoder_init.c index 037cd8e..d94d4fa 100644 --- a/liblss16_encoder_init.c +++ b/liblss16_encoder_init.c @@ -2,6 +2,10 @@  #include "liblss16.h"  #include <string.h> +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif +  int  liblss16_encoder_init(struct liblss16_encoder *encoder, const struct liblss16_header *header, diff --git a/liblss16_optimise.3 b/liblss16_optimise.3 new file mode 100644 index 0000000..0a9d6e5 --- /dev/null +++ b/liblss16_optimise.3 @@ -0,0 +1,81 @@ +.TH LIBLSS16_OPTIMISE 3 LIBLSS16 +.SH NAME +liblss16_optimise \- Optimise an image for best compression with LSS16 + +.SH SYNOPSIS +.nf +#include <liblss16.h> + +struct liblss16_colour { +	uint8_t \fIr\fP; +	uint8_t \fIg\fP; +	uint8_t \fIb\fP; +}; + +struct liblss16_header { +	uint16_t \fIwidth\fP; +	uint16_t \fIheight\fP; +	struct liblss16_colour \fIcolour_map\fP[16]; +}; + +void liblss16_optimise(struct liblss16_header *\fIheader\fP, uint8_t *\fIpixels\fP); +.fi +.PP +Link with +.IR -llss16 . + +.SH DESCRIPTION +The +.BR liblss16_optimise () +function reorders and deduplicates the colour palette +for an image so that it will compress optimally with LSS16. +.PP +.I header->width +shall be the width, in pixels, of the image. +.PP +.I header->height +shall be the height, in pixels, of the image. +.PP +.I header->colour_map +shall be the image's colour palette. +.PP +.I pixels +shall be a buffer of the colour index for +.I header->width*header->height +pixels. Ordered primarily from the top down +and secondarily from left to right. The colour +of a pixel encoded with the value +.I P +is determined by +.IR header->colour_map[P] . +Each +.B struct liblss16_colour +is encoded in sRGB with either 6 bits per channel +or 8 bits per channel +.RI ( .r +for the red channel, +.I .g +for the green channel, and +.I .b +for the blue channel). +.PP +Values in +.I pixels +must be 15 or less. The function will not validate the input. + +.PP +The function will rewrite +.I header->colour_map +and +.IR pixels . + +.SH RETURN VALUE +None. + +.SH ERRORS +The +.BR liblss16_optimise () +function cannot fail. + +.SH SEE ALSO +.BR liblss16 (7) diff --git a/liblss16_optimise.c b/liblss16_optimise.c index 5e69d85..f532a94 100644 --- a/liblss16_optimise.c +++ b/liblss16_optimise.c @@ -2,6 +2,10 @@  #include "liblss16.h"  #include <string.h> +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif +  void  liblss16_optimise(struct liblss16_header *header, uint8_t *pixels) @@ -37,6 +41,10 @@ liblss16_optimise(struct liblss16_header *header, uint8_t *pixels)  	width = (unsigned)header->width;  	width = width < 17U ? width : 17U;  	for (y = 0, p = 0; y < (unsigned)header->height; y++) { +#ifdef HARDEN +		for (x = 0; x < (unsigned)header->width; x++) +			pixels[p + x] &= 15U; +#endif  		colour = remap[pixels[p]];  		count = 1U;  		for (x = 1U; x < width; x++, p++) { @@ -0,0 +1,61 @@ +.TH LSS16 5 LIBLSS16 +.SH NAME +lss16 \- SYSLINUX \(dqad hoc\(dq 16-colour, 6-bit channel-depth image file format LSS16 + +.SH DESCRIPTION +LSS16 is run-length encoding compressed, lossless an image file format +using a 16-colour palette and sRGB 6-6-6. LSS16 is designed for bootloader splash +images which may be displayed on low-end legacy devices with limited image quality +capabilities. LSS16 does not support transparency. +.PP +LSS16 file consists how two parts: a 56 byte header followed by the pixel encoding. +.PP +Header format: +.RS +4-byte magic number: 3Dh, F3h, 13h, 14h. + +Image width (number of pixels horizontally): unsigned 16-bit integer, little endian. + +Image height (number of pixels horizontally): unsigned 16-bit integer, little endian, +however the most significant bit most be cleared. + +Colour palette: 16 RGB-tuples, each tuple is 3 bytes: red, green, blue. +The two most significant bits in each byte must be cleared.  +.RE +.PP +Pixel encoding format: +.RS +The pixels are encoded, row by row, from the top down, in a sequence of nibble. Each +row is encoded from left to right, and odd-nibble rows are padded with a zero-nibble. +Each encoded byte, is split into two nibbles; the lower part of the byte makes up the +first nibble, and the higher part of the byte makes up the second nibble. + +At the beginning of each row, the previous pixel is assumed to use the 0-indexed colour. + +If a nibble as the value of the the previous pixel colour index, a run-length is encoded, +otherwise the next pixel has the colour with the index encoded in the nibble. + +If the nibble encodes a run-length, it can either be 0 or the number of times the +previous pixel is repeated (excluding the already existing pixels). If the nibble +is 0, the next two nibbles, encodes in little-endian, a value +.IR N , +and the previous pixel is repeated +.IR N +16 +times (excluding the already existing pixels). +.RE +.PP +A 6-bit colour-channel +value +.I N +is mapped to 8-bits with the function +.I (N*255+31)/63 +(linear scaling). +.PP +LSS16 image files usually have the filename suffix +.RB \(dq .lss \(dq +or +.RB \(dq .16 \(dq. + +.SH SEE ALSO +.BR liblss16 (7), +.BR syslinux (1) diff --git a/lss16toppm.1 b/lss16toppm.1 new file mode 100644 index 0000000..560a76b --- /dev/null +++ b/lss16toppm.1 @@ -0,0 +1,98 @@ +.TH LSS16TOPPM 1 LIBLSS16 +.SH NAME +lss16toppm \- Convert an LSS16 file to a Portable Pixmap (PPM) file + +.SH SYNPOSIS +.B lss16toppm +.RB [ -map ] +.RI "< " lss16-file +.RI "> " ppm-file + +.SH DESCRIPTION +The +.B lss16toppm +utility converts the LSS16 image file +.I lss16-file +to a Portable Pixmap (PPM) file, storing it to +.IR ppm-file . +.PP +The PPM file will be raw (P6) and use full 8-bit colours +per channel (0-255). This means that the colours are +scaled up from 6-bits to 8-bits, per channel, as LSS16 +only uses 6 bits per channel. + +.SH OPTIONS +The +.B lss16toppm +utility parses each argument as an option, including +.RB \(dq -- \(dq. +.PP +The following option is supported: +.TP +.B -map +Output the image's colour palette to the standard error. +The image has 16 mapped colours, will be printed in order, +from index 0 up, in the format + +.nf +\fB\(dq#%02x%02x%02x=%u\(dq, \fP<\fIred\fP>\fB, \fP<\fIgreen\fP>\fB, \fP<\fIblue\fP>\fB, \fP<\fIcolour index\fP>. +.fi + +Although LSS16 uses 6 bit per colour channel, the output +colours are scaled up to and output as 8 bit per colour +channel. + +.SH OPERANDS +None. + +.SH STDIN +The standard input shall be the LSS16 file to convert. + +.SH INPUT FILES +None. + +.SH STDOUT +The image will be printed as a 8-bit raw Portable Pixmap +(P6 PPM) to the standard output. + +.SH STDERR +The standard error is used for diagnostic purposes. If the +.B -map +option is used, the colour palette will also be printed to +the standard error, apart from this, nothing is output to +the standard error if the exist value of the process is +.BR 0 . + +.SH OUTPUT FILES +None. + +.SH EXIT STATUS +The following exit values are returned: +.TP +0 +Successful completion. +.TP +1 +The standard input is not an valid LSS16 file. +.TP +2 +An error occured. + +.SH NOTES +The SYSLINUX implementation of the +.BR lss16toppm +utility does used the exit value +.BR 2 , +but instead always returns 1 on failure. + +.SH RATIONALE +The invocation syntax is inherited from the SYSLINUX +implementation of +.BR lss16toppm . +As is the output as raw 8-bit PPM (P6). + +.SH SEE ALSO +.BR lss16 (5), +.BR ppmtolss16 (1), +.BR liblss16 (7), +.BR syslinux (1) diff --git a/lss16toppm.c b/lss16toppm.c index 6dcff62..48c9b93 100644 --- a/lss16toppm.c +++ b/lss16toppm.c @@ -6,6 +6,10 @@  #include <string.h>  #include <unistd.h> +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif +  static const char *argv0 = "lss16toppm"; @@ -41,7 +45,7 @@ main(int argc, char *argv[])  	enum liblss16_decode_error error;  	int head_printed = 0;  	int print_colour_map = 0; -	int have_stdout, len; +	int have_stdout = 0, len;  	size_t i;  	/* cmdline syntax is inherited from the SYSLINUX implementation, @@ -52,11 +56,12 @@ main(int argc, char *argv[])  		argc--;  	} -	for (; argc; argc--, argv++) { +	for (; argc--; argv++) {  		if (!strcmp(*argv, "-map")) {  			print_colour_map = 1;  		} else {  			fprintf(stderr, "%s: Unknown option: %s\n", argv0, *argv); +			return 2;  		}  	} diff --git a/mk/dynamic.mk b/mk/dynamic.mk new file mode 100644 index 0000000..3960a59 --- /dev/null +++ b/mk/dynamic.mk @@ -0,0 +1,2 @@ +BIN_DEP = liblss16.$(LIBEXT) +BIN_LDFLAGS = -L. -llss16 diff --git a/mk/static.mk b/mk/static.mk new file mode 100644 index 0000000..cf32c17 --- /dev/null +++ b/mk/static.mk @@ -0,0 +1,2 @@ +BIN_DEP = liblss16.a +BIN_LDFLAGS = liblss16.a diff --git a/ppmtolss16.1 b/ppmtolss16.1 new file mode 100644 index 0000000..7bb3516 --- /dev/null +++ b/ppmtolss16.1 @@ -0,0 +1,93 @@ +.TH PPMTOLSS16 1 LIBLSS16 +.SH NAME +ppmtolss16 \- Convert a Portable Anymap (PNM) file to an LSS16 file + +.SH SYNPOSIS +.B ppmtolss16 +.RI "< " pnm-file +.RI "> " lss16-file + +.SH DESCRIPTION +The +.B ppmtolss16 +utility converts the Portable Anymap (PNM) image file +.I pnm-file +to an LSS16 image file, and stores it as +.IR lss16-file. +.PP +Despite the name +.BR ppmtolss16 , +the +.N ppmtolss16 +utility supports Portable Bitmap (PBM) and Portable Greymap (PGM) +in addition to Portable Pixmaps (PPM). Both plain (P1, P2, P3) +and raw (P4, P5, P6) files are supported. + +.SH OPTIONS +None, not even +.RB \(dq -- \(dq. + +.SH OPERANDS +None. + +.SH STDIN +The standard input shall be the Portable Anymap file to convert. + +.SH INPUT FILES +None. + +.SH STDOUT +The image will be printed as an LSS16 file to the standard output. + +.SH STDERR +The standard error is used for diagnostic purposes. + +.SH OUTPUT FILES +None. + +.SH EXIT STATUS +The following exit values are returned: +.TP +0 +Successful completion. +.TP +1 +The standard input is not an valid P1-P6 Portable Anymap file. +.TP +2 +The image is too large to be encoded with LSS16. +.TP +3 +An error occured. + +.SH NOTES +The SYSLINUX implementation of the +.BR ppmtolss16 +utility does used the exit valuess +.B 2 +and +.BR 3 , +but instead always returns 1 on failure. + +.SH RATIONALE +The invocation syntax and the name of the utility is +inherited from the SYSLINUX implementation of +.BR ppmtolss16 . +.PP +SYSLINUX's implementation of +.BR ppmtolss16 +supports forcing the colour palette, however because this +feature was poorly documented, misleading, and not generally +useful, this implementation does not support this. + +.SH HISTORY +Early versions of SYSLINUX's implementation of +.BR ppmtolss16 +only supported raw Portable Pixmap (P6 PPM) files +without comments. + +.SH SEE ALSO +.BR lss16 (5), +.BR lss16toppm (1), +.BR liblss16 (7), +.BR syslinux (1) | 
