Resync new repository with old repo r5166

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-09-17 18:18:44 +00:00
commit 57623d42eb
5691 changed files with 1361853 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config TIFF
bool "TIFF file generation utility"
default n
---help---
Enable support for the TIFF file generation program.
if TIFF
endif
+40
View File
@@ -0,0 +1,40 @@
############################################################################
# apps/graphics/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_TIFF),y)
CONFIGURED_APPS += graphics/tiff
endif
+72
View File
@@ -0,0 +1,72 @@
############################################################################
# apps/graphics/Makefile
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config # Current configuration
# Sub-directories
SUBDIRS = tiff
# Sub-directories that might need context setup
CNTXTDIRS =
all: nothing
.PHONY: nothing context depend clean distclean
nothing:
context:
@for dir in $(CNTXTDIRS) ; do \
$(MAKE) -C $$dir context TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
depend:
@for dir in $(SUBDIRS) ; do \
$(MAKE) -C $$dir depend TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
clean:
@for dir in $(SUBDIRS) ; do \
$(MAKE) -C $$dir clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
distclean: clean
@for dir in $(SUBDIRS) ; do \
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
-include Make.dep
+93
View File
@@ -0,0 +1,93 @@
############################################################################
# apps/graphics/tiff/Makefile
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# NuttX TIFF Creation Tool
ASRCS =
CSRCS = tiff_addstrip.c tiff_finalize.c tiff_initialize.c tiff_utils.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
ifeq ($(WINTOOL),y)
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
else
BIN = "$(APPDIR)/libapps$(LIBEXT)"
endif
ROOTDEPPATH = --dep-path .
# Common build
VPATH =
all: .built
.PHONY: context clean depend distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
.built: $(OBJS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $(BIN), $${obj}); \
done ; )
@touch .built
context:
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
@touch $@
depend: .depend
clean:
@rm -f *.o *~ .*.swp .built
$(call CLEAN)
distclean: clean
@rm -f Make.dep .depend
-include Make.dep
+15
View File
@@ -0,0 +1,15 @@
README for the TIFF Creation Library
=====================================
This directory contains a library that can be used to create TIFF image
files. This file was created for the purpose of supporting screen dumps
from an LCD. Howeve, the logic is general and could be used for most
any purpose.
The only usage documentation is in the (rather extensive) comments in
the file apps/include/tiff.h
Unit Test
=========
See apps/examples/tiff
+239
View File
@@ -0,0 +1,239 @@
/****************************************************************************
* apps/graphics/tiff/tiff_addstrip.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <apps/tiff.h>
#include "tiff_internal.h"
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_addstrip
*
* Description:
* Convert an RGB565 strip to an RGB888 strip and write it to tmpfile2.
*
* Add an image data strip. The size of the strip in pixels must be equal
* to the RowsPerStrip x ImageWidth values that were provided to
* tiff_initialize().
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state instance.
* buffer - A buffer containing a single row of data.
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip)
{
#ifdef CONFIG_DEBUG_GRAPHICS
size_t ntotal;
#endif
size_t nbytes;
FAR uint16_t *src;
FAR uint8_t *dest;
uint16_t rgb565;
int ret;
int i;
DEBUGASSERT(info->iobuffer != NULL);
/* Convert each RGB565 pixel to RGB888 */
src = (FAR uint16_t *)strip;
dest = info->iobuffer;
nbytes = 0;
#ifdef CONFIG_DEBUG_GRAPHICS
ntotal = 0;
#endif
for (i = 0; i < info->pps; i++)
{
/* Convert RGB565 to RGB888 */
rgb565 = *src++;
*dest++ = (rgb565 >> (11-3)) & 0xf8; /* Move bits 11-15 to 3-7 */
*dest++ = (rgb565 >> ( 5-2)) & 0xfc; /* Move bits 5-10 to 2-7 */
*dest++ = (rgb565 << ( 3)) & 0xf8; /* Move bits 0- 4 to 3-7 */
/* Update the byte count */
nbytes += 3;
#ifdef CONFIG_DEBUG_GRAPHICS
ntotal += 3;
#endif
/* Flush the conversion buffer to tmpfile2 when it becomes full */
if (nbytes > (info->iosize-3))
{
ret = tiff_write(info->tmp2fd, info->iobuffer, nbytes);
if (ret < 0)
{
return ret;
}
/* Reset to refill the conversion buffer */
dest = info->iobuffer;
nbytes = 0;
}
}
/* Flush any buffer data to tmpfile2 */
ret = tiff_write(info->tmp2fd, info->iobuffer, nbytes);
#ifdef CONFIG_DEBUG_GRAPHICS
ASSERT(ntotal == info->bps);
#endif
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_addstrip
*
* Description:
* Add an image data strip. The size of the strip in pixels must be equal
* to the RowsPerStrip x ImageWidth values that were provided to
* tiff_initialize().
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state instance.
* buffer - A buffer containing a single row of data.
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_addstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip)
{
ssize_t newsize;
int ret;
/* Add the new strip based on the color format. For FB_FMT_RGB16_565,
* will have to perform a conversion to RGB888.
*/
if (info->colorfmt == FB_FMT_RGB16_565)
{
ret = tiff_convstrip(info, strip);
}
/* For other formats, it is a simple write using the number of bytes per strip */
else
{
ret = tiff_write(info->tmp2fd, strip, info->bps);
}
if (ret < 0)
{
goto errout;
}
/* Write the byte count to the outfile and the offset to tmpfile1 */
ret = tiff_putint32(info->outfd, info->bps);
if (ret < 0)
{
goto errout;
}
info->outsize += 4;
ret = tiff_putint32(info->tmp1fd, info->tmp2size);
if (ret < 0)
{
goto errout;
}
info->tmp1size += 4;
/* Increment the size of tmp2file. */
info->tmp2size += info->bps;
/* Pad tmpfile2 as necessary achieve word alignment */
newsize = tiff_wordalign(info->tmp2fd, info->tmp2size);
if (newsize < 0)
{
ret = (int)newsize;
goto errout;
}
info->tmp2size = (size_t)newsize;
/* Increment the number of strips in the TIFF file */
info->nstrips++;
return OK;
errout:
tiff_abort(info);
return ret;
}
+439
View File
@@ -0,0 +1,439 @@
/****************************************************************************
* apps/graphics/tiff/tiff_finalize.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <apps/tiff.h>
#include "tiff_internal.h"
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_readifdentry
*
* Description:
* Read the IFD entry at the specified offset.
*
* Input Parameters:
* fd - File descriptor to rad from
* offset - Offset to read from
* ifdentry - Location to read the data
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static int tiff_readifdentry(int fd, off_t offset,
FAR struct tiff_ifdentry_s *ifdentry)
{
off_t newoffs;
ssize_t nbytes;
/* Seek to the read position */
newoffs = lseek(fd, offset, SEEK_SET);
if (newoffs == (off_t)-1)
{
return -errno;
}
/* Then read the IFD entry. Anything returned by tiff_read other than the
* size of the IFD entry would be an error.
*/
nbytes = tiff_read(fd, ifdentry, SIZEOF_IFD_ENTRY);
return nbytes == SIZEOF_IFD_ENTRY ? OK : -ENOSPC;
}
/****************************************************************************
* Name: tiff_writeifdentry
*
* Description:
* Write the IFD entry at the specified offset.
*
* Input Parameters:
* fd - File descriptor to rad from
* offset - Offset to read from
* ifdentry - Location to read the data
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static int tiff_writeifdentry(int fd, off_t offset,
FAR struct tiff_ifdentry_s *ifdentry)
{
off_t newoffs;
/* Seek to the write position */
newoffs = lseek(fd, offset, SEEK_SET);
if (newoffs == (off_t)-1)
{
return -errno;
}
/* Then write the IFD entry */
return tiff_write(fd, ifdentry, SIZEOF_IFD_ENTRY);
}
/****************************************************************************
* Name: tiff_cleanup
*
* Description:
* Normal clean-up after completion of the TIFF file creation
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF
* state instance.
*
* Returned Value:
* None
*
****************************************************************************/
static void tiff_cleanup(FAR struct tiff_info_s *info)
{
/* Close all opened files */
if (info->outfd >= 0)
{
(void)close(info->outfd);
}
info->outfd = -1;
if (info->tmp1fd >= 0)
{
(void)close(info->tmp1fd);
}
info->tmp1fd = -1;
if (info->tmp2fd >= 0)
{
(void)close(info->tmp2fd);
}
info->tmp2fd = -1;
/* And remove the temporary files */
(void)unlink(info->tmpfile1);
(void)unlink(info->tmpfile2);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_finalize
*
* Description:
* Finalize the TIFF output file, completing the TIFF file creation steps.
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state
* instance.
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_finalize(FAR struct tiff_info_s *info)
{
struct tiff_ifdentry_s ifdentry;
FAR uint8_t *ptr;
size_t maxoffsets;
#ifdef CONFIG_DEBUG_GRAPHICS
size_t total;
#endif
off_t offset;
int ret;
int i;
int j;
/* Put all of the pieces together to create the final output file. There
* are three pieces:
*
* 1) outfile: The partial output file containing the header, IFD and strip
* counts. This includes the StripOffsets and StripByteCounts that need
* to be updated. Size=outsize;
* 2) tmpfile1: This contains the offsets into tmpfile3 for each strip. The
* size of this file is tmp1size. These offsets are relative to the
* beginning of tmpfile3 and need to be offset by outsize+tmp1size.
* 3) tmpfile3: The strip data. Size is tmp2size. This is raw image data;
* no fixups are required.
*/
DEBUGASSERT(info && info->outfd >= 0 && info->tmp1fd >= 0 && info->tmp2fd >= 0);
DEBUGASSERT((info->outsize & 3) == 0 && (info->tmp1size & 3) == 0);
/* Fix-up the count value in the StripByteCounts IFD entry in the outfile.
* The actual number of strips was unknown at the time that the IFD entry
* was written.
*/
ret = tiff_readifdentry(info->outfd, info->filefmt->sbcifdoffset, &ifdentry);
if (ret < 0)
{
goto errout;
}
tiff_put32(ifdentry.count, info->nstrips);
ret = tiff_writeifdentry(info->outfd, info->filefmt->sbcifdoffset, &ifdentry);
if (ret < 0)
{
goto errout;
}
/* Fix-up the count and offset values in the StripOffsets IFD entry in the
* outfile. The StripOffsets data will be stored immediately after the
* outfile, hence, the correct offset is outsize.
*/
ret = tiff_readifdentry(info->outfd, info->filefmt->soifdoffset, &ifdentry);
if (ret < 0)
{
goto errout;
}
tiff_put32(ifdentry.count, info->nstrips);
tiff_put32(ifdentry.offset, info->outsize);
ret = tiff_writeifdentry(info->outfd, info->filefmt->soifdoffset, &ifdentry);
if (ret < 0)
{
goto errout;
}
/* Rewind to the beginning of tmpfile1 */
offset = lseek(info->tmp1fd, 0, SEEK_SET);
if (offset == (off_t)-1)
{
ret = -errno;
goto errout;
}
/* Seek to the end of the outfile */
ret = lseek(info->outfd, 0, SEEK_END);
if (offset == (off_t)-1)
{
ret = -errno;
goto errout;
}
/* Now read strip offset data from tmpfile1, update the offsets, and write
* the updated offsets to the outfile. The strip data will begin at offset
* outsize + tmp1size;
*/
maxoffsets = info->iosize >> 2;
#ifdef CONFIG_DEBUG_GRAPHICS
total = 0;
#endif
for (i = 0; i < info->nstrips; )
{
size_t noffsets;
ssize_t nbytes;
/* Read a group of up to 32-bit values */
noffsets = info->nstrips - i;
if (noffsets > maxoffsets)
{
noffsets = maxoffsets;
}
nbytes = tiff_read(info->tmp1fd, info->iobuffer, noffsets << 2);
/* If an error occurs or we fail to read exactly this number of
* bytes, then something bad happened.
*/
if (nbytes != noffsets << 2)
{
goto errout;
}
/* Fix up the offsets */
for (j = 0, ptr = info->iobuffer;
j < noffsets;
j++, ptr += 4)
{
uint32_t stripoff = tiff_get32(ptr);
stripoff += (info->outsize + info->tmp1size);
tiff_put32(ptr, stripoff);
}
/* Then write the corrected offsets to the outfile */
ret = tiff_write(info->outfd, info->iobuffer, nbytes);
if (ret < 0)
{
goto errout;
}
/* Update the count of offsets written */
i += noffsets;
#ifdef CONFIG_DEBUG_GRAPHICS
total += nbytes;
#endif
}
#ifdef CONFIG_DEBUG_GRAPHICS
ASSERT(total == info->tmp1size);
#endif
/* Rewind to the beginning of tmpfile2 */
offset = lseek(info->tmp2fd, 0, SEEK_SET);
if (offset == (off_t)-1)
{
ret = -errno;
goto errout;
}
/* Finally, copy the tmpfile2 to the end of the outfile */
#ifdef CONFIG_DEBUG_GRAPHICS
total = 0;
#endif
for (;;)
{
ssize_t nbytes;
/* Read a block of data from tmpfile2 */
nbytes = tiff_read(info->tmp2fd, info->iobuffer, info->iosize);
/* Check for tead errors and for end-of-file */
if (nbytes < 0)
{
ret = (int)nbytes;
goto errout;
}
else if (nbytes == 0)
{
break;
}
/* Then copy the data to the outfile */
ret = tiff_write(info->outfd, info->iobuffer, nbytes);
if (ret < 0)
{
goto errout;
}
#ifdef CONFIG_DEBUG_GRAPHICS
total += nbytes;
#endif
}
#ifdef CONFIG_DEBUG_GRAPHICS
ASSERT(total == info->tmp2size);
#endif
/* Close all files and return success */
tiff_cleanup(info);
return OK;
errout:
tiff_abort(info);
return ret;
}
/************************************************************************************
* Name: tiff_abort
*
* Description:
* Abort the TIFF file creation and create-up resources.
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state instance.
*
* Returned Value:
* None
*
************************************************************************************/
void tiff_abort(FAR struct tiff_info_s *info)
{
/* Perform normal cleanup */
tiff_cleanup(info);
/* But then delete the output file as well */
(void)unlink(info->outfile);
}
+910
View File
@@ -0,0 +1,910 @@
/****************************************************************************
* apps/graphics/tiff/tiff_initialize.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <apps/tiff.h>
#include "tiff_internal.h"
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* Bi-level Images
*
* Offset Description Contents/Notes
* Header: 0 Byte Order "II" or "MM"
* 2 Magic Number 42
* 4 1st IFD offset 10
* 8 [2 bytes padding]
* IFD: 10 Number of Directory Entries 13
* 12 NewSubfileType
* 24 ImageWidth Number of columns is a user parameter
* 36 ImageLength Number of rows is a user parameter
* 48 Compression Hard-coded no compression (for now)
* 60 PhotometricInterpretation Value is a user parameter
* 72 StripOffsets Offset and count determined as strips added
* 84 RowsPerStrip Value is a user parameter
* 96 StripByteCounts Offset and count determined as strips added
* 108 XResolution Value is a user parameter
* 120 YResolution Value is a user parameter
* 132 Resolution Unit Hard-coded to "inches"
* 144 Software
* 156 DateTime
* 168 Next IFD offset 0
* 170 [2 bytes padding]
* Values:
* 172 XResolution Hard-coded to 300/1
* 180 YResolution Hard-coded to 300/1
* 188 "NuttX" Length = 6 (including NUL terminator)
* 194 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator)
* 214 [2 bytes padding]
* 216 StripByteCounts Beginning of strip byte counts
* xxx StripOffsets Beginning of strip offsets
* xxx [Probably padding]
* xxx Data for strips Beginning of strip data
*/
#define TIFF_IFD_OFFSET (SIZEOF_TIFF_HEADER+2)
#define TIFF_BILEV_NIFDENTRIES 13
#define TIFF_BILEV_STRIPIFDOFFS 72
#define TIFF_BILEV_STRIPBCIFDOFFS 96
#define TIFF_BILEV_VALOFFSET 172
#define TIFF_BILEV_XRESOFFSET 172
#define TIFF_BILEV_YRESOFFSET 180
#define TIFF_BILEV_SWOFFSET 188
#define TIFF_BILEV_DATEOFFSET 194
#define TIFF_BILEV_STRIPBCOFFSET 216
#define TIFF_SOFTWARE_STRING "NuttX"
#define TIFF_SOFTWARE_STRLEN 6
#define TIFF_DATETIME_FORMAT "%Y:%m:%d %H:%M:%S"
#define TIFF_DATETIME_STRLEN 20
/* Greyscale Images have one additional IFD entry: BitsPerSample (4 or 8)
*
* Header: 0 Byte Order "II" or "MM"
* 2 Magic Number 42
* 4 1st IFD offset 10
* 8 [2 bytes padding]
* IFD: 10 Number of Directory Entries 14
* 12 NewSubfileType
* 24 ImageWidth Number of columns is a user parameter
* 36 ImageLength Number of rows is a user parameter
* 48 BitsPerSample
* 60 Compression Hard-coded no compression (for now)
* 72 PhotometricInterpretation Value is a user parameter
* 84 StripOffsets Offset and count determined as strips added
* 96 RowsPerStrip Value is a user parameter
* 108 StripByteCounts Offset and count determined as strips added
* 120 XResolution Value is a user parameter
* 132 YResolution Value is a user parameter
* 144 Resolution Unit Hard-coded to "inches"
* 156 Software
* 168 DateTime
* 180 Next IFD offset 0
* 182 [2 bytes padding]
* Values:
* 184 XResolution Hard-coded to 300/1
* 192 YResolution Hard-coded to 300/1
* 200 "NuttX" Length = 6 (including NUL terminator)
* 206 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator)
* 226 [2 bytes padding]
* 228 StripByteCounts Beginning of strip byte counts
* xxx StripOffsets Beginning of strip offsets
* xxx [Probably padding]
* xxx Data for strips Beginning of strip data
*/
#define TIFF_GREY_NIFDENTRIES 14
#define TIFF_GREY_STRIPIFDOFFS 84
#define TIFF_GREY_STRIPBCIFDOFFS 108
#define TIFF_GREY_VALOFFSET 184
#define TIFF_GREY_XRESOFFSET 184
#define TIFF_GREY_YRESOFFSET 192
#define TIFF_GREY_SWOFFSET 200
#define TIFF_GREY_DATEOFFSET 206
#define TIFF_GREY_STRIPBCOFFSET 228
/* RGB Images have two additional IFD entries: BitsPerSample (8,8,8) and
* SamplesPerPixel (3):
*
* Header: 0 Byte Order "II" or "MM"
* 2 Magic Number 42
* 4 1st IFD offset 10
* 8 [2 bytes padding]
* IFD: 10 Number of Directory Entries 15
* 12 NewSubfileType
* 24 ImageWidth Number of columns is a user parameter
* 36 ImageLength Number of rows is a user parameter
* 48 BitsPerSample 8, 8, 8
* 60 Compression Hard-coded no compression (for now)
* 72 PhotometricInterpretation Value is a user parameter
* 84 StripOffsets Offset and count determined as strips added
* 96 SamplesPerPixel Hard-coded to 3
* 108 RowsPerStrip Value is a user parameter
* 120 StripByteCounts Offset and count determined as strips added
* 132 XResolution Value is a user parameter
* 144 YResolution Value is a user parameter
* 156 Resolution Unit Hard-coded to "inches"
* 168 Software
* 180 DateTime
* 192 Next IFD offset 0
* 194 [2 bytes padding]
* Values:
* 196 XResolution Hard-coded to 300/1
* 204 YResolution Hard-coded to 300/1
* 212 BitsPerSample 8, 8, 8
* 218 [2 bytes padding]
* 220 "NuttX" Length = 6 (including NUL terminator)
* 226 "YYYY:MM:DD HH:MM:SS" Length = 20 (ncluding NUL terminator)
* 246 [2 bytes padding]
* 248 StripByteCounts Beginning of strip byte counts
* xxx StripOffsets Beginning of strip offsets
* xxx [Probably padding]
* xxx Data for strips Beginning of strip data
*/
#define TIFF_RGB_NIFDENTRIES 15
#define TIFF_RGB_STRIPIFDOFFS 84
#define TIFF_RGB_STRIPBCIFDOFFS 120
#define TIFF_RGB_VALOFFSET 196
#define TIFF_RGB_XRESOFFSET 196
#define TIFF_RGB_YRESOFFSET 204
#define TIFF_RGB_BPSOFFSET 212
#define TIFF_RGB_SWOFFSET 220
#define TIFF_RGB_DATEOFFSET 226
#define TIFF_RGB_STRIPBCOFFSET 248
/* Debug *******************************************************************/
/* CONFIG_DEBUG_TIFFOFFSETS may be defined (along with CONFIG_DEBUG and
* CONFIG_DEBUG_GRAPHICS) in order to verify the pre-determined TIFF file
* offsets.
*/
#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG_TIFFOFFSETS
#endif
#ifdef CONFIG_DEBUG_TIFFOFFSETS
# define tiff_offset(o,l) (o) += (l)
# define tiff_checkoffs(o,x) ASSERT((o) == (x))
#else
# define tiff_offset(o,l)
# define tiff_checkoffs(o,x)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static const struct tiff_filefmt_s g_bilevinfo =
{
TIFF_BILEV_NIFDENTRIES, /* nifdentries, Number of IFD entries */
TIFF_BILEV_STRIPIFDOFFS, /* soifdoffset, Offset to StripOffset IFD entry */
TIFF_BILEV_STRIPBCIFDOFFS, /* sbcifdoffset, Offset to StripByteCount IFD entry */
TIFF_BILEV_VALOFFSET, /* valoffset, Offset to first values */
TIFF_BILEV_XRESOFFSET, /* xresoffset, Offset to XResolution values */
TIFF_BILEV_YRESOFFSET, /* yresoffset, Offset to yResolution values */
TIFF_BILEV_SWOFFSET, /* swoffset, Offset to Software string */
TIFF_BILEV_DATEOFFSET, /* dateoffset, Offset to DateTime string */
TIFF_BILEV_STRIPBCOFFSET /* sbcoffset, Offset to StripByteCount values */
};
static const struct tiff_filefmt_s g_greyinfo =
{
TIFF_GREY_NIFDENTRIES, /* nifdentries, Number of IFD entries */
TIFF_GREY_STRIPIFDOFFS, /* soifdoffset, Offset to StripOffset IFD entry */
TIFF_GREY_STRIPBCIFDOFFS, /* sbcifdoffset, Offset to StripByteCount IFD entry */
TIFF_GREY_VALOFFSET, /* valoffset, Offset to first values */
TIFF_GREY_XRESOFFSET, /* xresoffset, Offset to XResolution values */
TIFF_GREY_YRESOFFSET, /* yresoffset, Offset to yResolution values */
TIFF_GREY_SWOFFSET, /* swoffset, Offset to Software string */
TIFF_GREY_DATEOFFSET, /* dateoffset, Offset to DateTime string */
TIFF_GREY_STRIPBCOFFSET /* sbcoffset, Offset to StripByteCount values */
};
static const struct tiff_filefmt_s g_rgbinfo =
{
TIFF_RGB_NIFDENTRIES, /* nifdentries, Number of IFD entries */
TIFF_RGB_STRIPIFDOFFS, /* soifdoffset, Offset to StripOffset IFD entry */
TIFF_RGB_STRIPBCIFDOFFS, /* sbcifdoffset, Offset to StripByteCount IFD entry */
TIFF_RGB_VALOFFSET, /* valoffset, Offset to first values */
TIFF_RGB_XRESOFFSET, /* xresoffset, Offset to XResolution values */
TIFF_RGB_YRESOFFSET, /* yresoffset, Offset to yResolution values */
TIFF_RGB_SWOFFSET, /* swoffset, Offset to Software string */
TIFF_RGB_DATEOFFSET, /* dateoffset, Offset to DateTime string */
TIFF_RGB_STRIPBCOFFSET /* sbcoffset, Offset to StripByteCount values */
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_putheader
*
* Description:
* Setup to create a new TIFF file.
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state
* instance.
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static inline int tiff_putheader(FAR struct tiff_info_s *info)
{
struct tiff_header_s hdr;
int ret;
/* 0-1: Byte order */
#ifdef CONFIG_ENDIAN_BIG
hdr.order[0] = 'M'; /* "MM"=big endian */
hdr.order[1] = 'M';
#else
hdr.order[0] = 'I'; /* "II"=little endian */
hdr.order[1] = 'I';
#endif
/* 2-3: 42 in appropriate byte order */
tiff_put16(hdr.magic, 42);
/* 4-7: Offset to the first IFD */
tiff_put32(hdr.offset, TIFF_IFD_OFFSET);
/* Write the header to the output file */
ret = tiff_write(info->outfd, &hdr, SIZEOF_TIFF_HEADER);
if (ret != OK)
{
return ret;
}
/* Two pad bytes following the header */
ret = tiff_putint16(info->outfd, 0);
return ret;
}
/****************************************************************************
* Name: tiff_putifdentry
*
* Description:
* Write an IFD entry to outfile
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state
* instance.
* tag - The value for the IFD tag field
* type - The value for the IFD type field
* count - The value for the IFD count field
* offset - The value for the IFD offset field
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static int tiff_putifdentry(FAR struct tiff_info_s *info, uint16_t tag,
uint16_t type, uint32_t count, uint32_t offset)
{
struct tiff_ifdentry_s ifd;
tiff_put16(ifd.tag, tag);
tiff_put16(ifd.type, type);
tiff_put32(ifd.count, count);
tiff_put32(ifd.offset, offset);
return tiff_write(info->outfd, &ifd, SIZEOF_IFD_ENTRY);
}
/****************************************************************************
* Name: tiff_putifdentry
*
* Description:
* Write an IFD with a 16-bit immediate value
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state
* instance.
* tag - The value for the IFD tag field
* type - The value for the IFD type field
* count - The value for the IFD count field
* value - The 16-bit immediate value
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static int tiff_putifdentry16(FAR struct tiff_info_s *info, uint16_t tag,
uint16_t type, uint32_t count, uint16_t value)
{
union
{
uint8_t b[4];
uint32_t w;
} u;
u.w = 0;
tiff_put16(u.b, value);
return tiff_putifdentry(info, tag, type, count, u.w);
}
/****************************************************************************
* Name: tiff_datetime
*
* Description:
* Get the DateTime string
*
* Input Parameters:
*
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
static int tiff_datetime(FAR char *timbuf, unsigned int buflen)
{
struct timespec ts;
struct tm tm;
int ret;
/* Get the current time */
ret = clock_gettime(CLOCK_REALTIME, &ts);
if (ret < 0)
{
gdbg("clock_gettime failed: %d\n", errno);
return ERROR;
}
/* Break the current time up into the format needed by strftime */
(void)gmtime_r((FAR const time_t*)&ts.tv_sec, &tm);
/* Comvert the current time in the TIFF format */
(void)strftime(timbuf, buflen, TIFF_DATETIME_FORMAT, &tm);
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_initialize
*
* Description:
* Setup to create a new TIFF file.
*
* Input Parameters:
* info - A pointer to the caller allocated parameter passing/TIFF state instance.
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_initialize(FAR struct tiff_info_s *info)
{
uint16_t val16;
#if CONFIG_DEBUG_TIFFOFFSETS
off_t offset = 0;
#endif
char timbuf[TIFF_DATETIME_STRLEN + 8];
int ret = -EINVAL;
DEBUGASSERT(info && info->outfile && info->tmpfile1 && info->tmpfile2);
/* Open all output files */
info->outfd = open(info->outfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (info->outfd < 0)
{
gdbg("Failed to open %s for reading/writing: %d\n", info->outfile, errno);
goto errout;
}
info->tmp1fd = open(info->tmpfile1, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (info->tmp1fd < 0)
{
gdbg("Failed to open %s for reading/writing: %d\n", info->tmpfile1, errno);
goto errout;
}
info->tmp2fd = open(info->tmpfile2, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (info->tmp2fd < 0)
{
gdbg("Failed to open %s for reading/writing: %d\n", info->tmpfile2, errno);
goto errout;
}
/* Make some decisions using the color format. Only the following are
* supported:
*/
info->pps = info->imgwidth * info->rps; /* Pixels per strip */
switch (info->colorfmt)
{
case FB_FMT_Y1: /* BPP=1, monochrome, 0=black */
info->filefmt = &g_bilevinfo; /* Bi-level file image file info */
info->imgflags = IMGFLAGS_FMT_Y1; /* Bit encoded image characteristics */
info->bps = (info->pps + 7) >> 3; /* Bytes per strip */
break;
case FB_FMT_Y4: /* BPP=4, 4-bit greyscale, 0=black */
info->filefmt = &g_greyinfo; /* Greyscale file image file info */
info->imgflags = IMGFLAGS_FMT_Y4; /* Bit encoded image characteristics */
info->bps = (info->pps + 1) >> 1; /* Bytes per strip */
break;
case FB_FMT_Y8: /* BPP=8, 8-bit greyscale, 0=black */
info->filefmt = &g_greyinfo; /* Greyscale file image file info */
info->imgflags = IMGFLAGS_FMT_Y8; /* Bit encoded image characteristics */
info->bps = info->pps; /* Bytes per strip */
break;
case FB_FMT_RGB16_565: /* BPP=16 R=6, G=6, B=5 */
info->filefmt = &g_rgbinfo; /* RGB file image file info */
info->imgflags = IMGFLAGS_FMT_RGB16_565; /* Bit encoded image characteristics */
info->bps = 3 * info->pps; /* Bytes per strip */
break;
case FB_FMT_RGB24: /* BPP=24 R=8, G=8, B=8 */
info->filefmt = &g_rgbinfo; /* RGB file image file info */
info->imgflags = IMGFLAGS_FMT_RGB24; /* Bit encoded image characteristics */
info->bps = 3 *info->pps; /* Bytes per strip */
break;
default:
gdbg("Unsupported color format: %d\n", info->colorfmt);
return -EINVAL;
}
/* Write the TIFF header data to the outfile:
*
* Header: 0 Byte Order "II" or "MM"
* 2 Magic Number 42
* 4 1st IFD offset 10
* 8 [2 bytes padding]
*/
ret = tiff_putheader(info);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, TIFF_IFD_OFFSET);
/* Write the Number of directory entries
*
* All formats: Offset 10 Number of Directory Entries 12
*/
ret = tiff_putint16(info->outfd, info->filefmt->nifdentries);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 2);
/* Write the NewSubfileType IFD entry
*
* All formats: Offset 12 NewSubfileType
*/
ret = tiff_putifdentry16(info, IFD_TAG_NEWSUBFILETYPE, IFD_FIELD_LONG, 1, 0);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write ImageWidth and ImageLength
*
* All formats: Offset 24 ImageWidth Number of columns is a user parameter
* 36 ImageLength Number of rows is a user parameter
*/
ret = tiff_putifdentry16(info, IFD_TAG_IMAGEWIDTH, IFD_FIELD_SHORT, 1, info->imgwidth);
if (ret == OK)
{
ret= tiff_putifdentry16(info, IFD_TAG_IMAGELENGTH, IFD_FIELD_SHORT, 1, info->imgheight);
}
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 2*SIZEOF_IFD_ENTRY);
/* Write BitsPerSample
*
* Bi-level Images: None
* Greyscale: Offset 48 BitsPerSample (4 or 8)
* RGB: Offset 48 BitsPerSample (8,8,8)
*/
tiff_checkoffs(offset, 48);
if (IMGFLAGS_ISGREY(info->imgflags))
{
if (IMGFLAGS_ISGREY8(info->imgflags))
{
val16 = 8;
}
else
{
val16 = 4;
}
ret = tiff_putifdentry16(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 1, val16);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
}
else if (IMGFLAGS_ISRGB(info->imgflags))
{
ret = tiff_putifdentry(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 3, TIFF_RGB_BPSOFFSET);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
}
/* Write Compression:
*
* Bi-level Images: Offset 48 Hard-coded no compression (for now)
* Greyscale: Offset 60 " " " " "" " " " " " "
* RGB: Offset 60 " " " " "" " " " " " "
*/
ret = tiff_putifdentry16(info, IFD_TAG_COMPRESSION, IFD_FIELD_SHORT, 1, TAG_COMP_NONE);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write PhotometricInterpretation:
*
* Bi-level Images: Offset 48 Hard-coded BlackIsZero
* Greyscale: Offset 72 Hard-coded BlackIsZero
* RGB: Offset 72 Hard-coded RGB
*/
if (IMGFLAGS_ISRGB(info->imgflags))
{
val16 = TAG_PMI_RGB;
}
else
{
val16 = TAG_PMI_BLACK;
}
ret = tiff_putifdentry16(info, IFD_TAG_PMI, IFD_FIELD_SHORT, 1, val16);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write StripOffsets:
*
* Bi-level Images: Offset 72 Value determined by switch statement above
* Greyscale: Offset 84 Value determined by switch statement above
* RGB: Offset 84 Value determined by switch statement above
*/
tiff_checkoffs(offset, info->filefmt->soifdoffset);
ret = tiff_putifdentry(info, IFD_TAG_STRIPOFFSETS, IFD_FIELD_LONG, 0, 0);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write SamplesPerPixel
*
* Bi-level Images: N/A
* Greyscale: N/A
* RGB: Offset 96 Hard-coded to 3
*/
if (IMGFLAGS_ISRGB(info->imgflags))
{
ret = tiff_putifdentry16(info, IFD_TAG_SAMPLESPERPIXEL, IFD_FIELD_SHORT, 1, 3);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
}
/* Write RowsPerStrip:
*
* Bi-level Images: Offset 84 Value is a user parameter
* Greyscale: Offset 96 Value is a user parameter
* RGB: Offset 108 Value is a user parameter
*/
ret = tiff_putifdentry16(info, IFD_TAG_ROWSPERSTRIP, IFD_FIELD_SHORT, 1, info->rps);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write StripByteCounts:
*
* Bi-level Images: Offset 96 Count determined as strips added, Value offset = 216
* Greyscale: Offset 108 Count determined as strips added, Value offset = 228
* RGB: Offset 120 Count determined as strips added, Value offset = 248
*/
tiff_checkoffs(offset, info->filefmt->sbcifdoffset);
ret = tiff_putifdentry(info, IFD_TAG_STRIPCOUNTS, IFD_FIELD_LONG, 0, info->filefmt->sbcoffset);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write XResolution and YResolution:
*
* Bi-level Images: Offset 108 and 120, Values are a user parameters
* Greyscale: Offset 120 and 132, Values are a user parameters
* RGB: Offset 132 and 144, Values are a user parameters
*/
ret = tiff_putifdentry(info, IFD_TAG_XRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->xresoffset);
if (ret == OK)
{
ret = tiff_putifdentry(info, IFD_TAG_YRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->yresoffset);
}
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 2*SIZEOF_IFD_ENTRY);
/* Write ResolutionUnit:
*
* Bi-level Images: Offset 132, Hard-coded to "inches"
* Greyscale: Offset 144, Hard-coded to "inches"
* RGB: Offset 156, Hard-coded to "inches"
*/
ret = tiff_putifdentry16(info, IFD_TAG_RESUNIT, IFD_FIELD_SHORT, 1, TAG_RESUNIT_INCH);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write Software:
*
* Bi-level Images: Offset 144 Count, Hard-coded "NuttX"
* Greyscale: Offset 156 Count, Hard-coded "NuttX"
* RGB: Offset 168 Count, Hard-coded "NuttX"
*/
ret = tiff_putifdentry(info, IFD_TAG_SOFTWARE, IFD_FIELD_ASCII, TIFF_SOFTWARE_STRLEN, info->filefmt->swoffset);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write DateTime:
*
* Bi-level Images: Offset 156 Count, Format "YYYY:MM:DD HH:MM:SS"
* Greyscale: Offset 168 Count, Format "YYYY:MM:DD HH:MM:SS"
* RGB: Offset 180 Count, Format "YYYY:MM:DD HH:MM:SS"
*/
ret = tiff_putifdentry(info, IFD_TAG_DATETIME, IFD_FIELD_ASCII, TIFF_DATETIME_STRLEN, info->filefmt->dateoffset);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, SIZEOF_IFD_ENTRY);
/* Write Next IFD Offset and 2 bytes of padding:
*
* Bi-level Images: Offset 168, Next IFD offset
* Offset 170, [2 bytes padding]
* Greyscale: Offset 180, Next IFD offset
* Offset 182, [2 bytes padding]
* RGB: Offset 192, Next IFD offset
* Offset 194, [2 bytes padding]
*/
ret = tiff_putint32(info->outfd, 0);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 4);
/* Now we begin the value section of the file */
tiff_checkoffs(offset, info->filefmt->valoffset);
/* Write the XResolution and YResolution data:
*
* Bi-level Images: Offset 172 Count, Hard-coded to 300/1
* Offset 180 Count, Hard-coded to 300/1
* Greyscale: Offset 184 Count, Hard-coded to 300/1
* Offset 192 Count, Hard-coded to 300/1
* RGB: Offset 196 Count, Hard-coded to 300/1
* Offset 204 Count, Hard-coded to 300/1
*/
tiff_checkoffs(offset, info->filefmt->xresoffset);
ret = tiff_putint32(info->outfd, 300);
if (ret == OK)
{
ret = tiff_putint32(info->outfd, 1);
}
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 8);
tiff_checkoffs(offset, info->filefmt->yresoffset);
ret = tiff_putint32(info->outfd, 300);
if (ret == OK)
{
ret = tiff_putint32(info->outfd, 1);
}
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 8);
/* Write RGB BitsPerSample Data:
*
* Bi-level Images: N/A
* Greyscale: N/A
* RGB: Offset 212 BitsPerSample (8,8,8)
* Offset 218 [2 bytes padding]
*/
if (IMGFLAGS_ISRGB(info->imgflags))
{
tiff_checkoffs(offset, TIFF_RGB_BPSOFFSET);
tiff_putint16(info->outfd, 8);
tiff_putint16(info->outfd, 8);
tiff_putint16(info->outfd, 8);
tiff_putint16(info->outfd, 0);
tiff_offset(offset, 8);
}
/* Write the Software string:
*
*
* Bi-level Images: Offset 188, Hard-coded "NuttX"
* Greyscale: Offset 200, Hard-coded "NuttX"
* RGB: Offset 220, Hard-coded "NuttX"
*/
tiff_checkoffs(offset, info->filefmt->swoffset);
ret = tiff_putstring(info->outfd, TIFF_SOFTWARE_STRING, TIFF_SOFTWARE_STRLEN);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, TIFF_SOFTWARE_STRLEN);
/* Write the DateTime string:
*
*
* Bi-level Images: Offset 188, Format "YYYY:MM:DD HH:MM:SSS"
* Greyscale: Offset 200, Hard-coded "NuttX"
* RGB: Offset 220, Hard-coded "NuttX"
*/
tiff_checkoffs(offset, info->filefmt->dateoffset);
ret = tiff_datetime(timbuf, TIFF_DATETIME_STRLEN + 8);
if (ret < 0)
{
goto errout;
}
ret = tiff_putstring(info->outfd, timbuf, TIFF_DATETIME_STRLEN);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, TIFF_DATETIME_STRLEN);
/* Add two bytes of padding */
ret = tiff_putint16(info->outfd, 0);
if (ret < 0)
{
goto errout;
}
tiff_offset(offset, 2);
/* And that should do it! */
tiff_checkoffs(offset, info->filefmt->sbcoffset);
info->outsize = info->filefmt->sbcoffset;
return OK;
errout:
tiff_abort(info);
return ret;
}
+211
View File
@@ -0,0 +1,211 @@
/****************************************************************************
* apps/graphics/tiff/tiff_internal.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __APPS_GRAPHICS_TIFF_TIFF_INTERNAL_H
#define __APPS_GRAPHICS_TIFF_TIFF_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/nx/nxglib.h>
#include <apps/tiff.h>
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* Image Type ***************************************************************/
#define IMGFLAGS_BILEV_BIT (1 << 0)
#define IMGFLAGS_GREY_BIT (1 << 1)
#define IMGFLAGS_GREY8_BIT (1 << 2)
#define IMGFLAGS_RGB_BIT (1 << 3)
#define IMGFLAGS_RGB565_BIT (1 << 4)
#define IMGFLAGS_FMT_Y1 (IMGFLAGS_BILEV_BIT)
#define IMGFLAGS_FMT_Y4 (IMGFLAGS_GREY_BIT)
#define IMGFLAGS_FMT_Y8 (IMGFLAGS_GREY_BIT|IMGFLAGS_GREY8_BIT)
#define IMGFLAGS_FMT_RGB16_565 (IMGFLAGS_RGB_BIT)
#define IMGFLAGS_FMT_RGB24 (IMGFLAGS_RGB_BIT|IMGFLAGS_RGB565_BIT)
#define IMGFLAGS_ISBILEV(f) \
(((f) & IMGFLAGS_BILEV_BIT) != 0)
#define IMGFLAGS_ISGREY(f) \
(((f) & IMGFLAGS_GREY_BIT) != 0)
#define IMGFLAGS_ISGREY4(f) \
(((f) & (IMGFLAGS_GREY_BIT|IMGFLAGS_GREY8_BIT)) == IMGFLAGS_GREY_BIT)
#define IMGFLAGS_ISGREY8(f) \
(((f) & (IMGFLAGS_GREY_BIT|IMGFLAGS_GREY8_BIT)) == (IMGFLAGS_GREY_BIT|IMGFLAGS_GREY8_BIT))
#define IMGFLAGS_ISRGB(f) \
(((f) & IMGFLAGS_FMT_RGB24) != 0)
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_read
*
* Description:
* Read TIFF data from the specified file
*
* Input Parameters:
* fd - Open file descriptor to read from
* buffer - Read-only buffer containing the data to be written
* count - The number of bytes to write
*
* Returned Value:
* On success, then number of bytes read; Zero is returned on EOF.
* Otherwise, a negated errno value on failure.
*
****************************************************************************/
EXTERN ssize_t tiff_read(int fd, FAR void *buffer, size_t count);
/****************************************************************************
* Name: tiff_write
*
* Description:
* Write TIFF data to the specified file
*
* Input Parameters:
* fd - Open file descriptor to write to
* buffer - Read-only buffer containing the data to be written
* count - The number of bytes to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
EXTERN int tiff_write(int fd, FAR const void *buffer, size_t count);
/****************************************************************************
* Name: tiff_putint16
*
* Description:
* Write two bytes to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* value - The 2-byte, uint16_t value to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
EXTERN int tiff_putint16(int fd, uint16_t value);
/****************************************************************************
* Name: tiff_putint32
*
* Description:
* Write four bytes to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* value - The 4-byte, uint32_t value to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
EXTERN int tiff_putint32(int fd, uint32_t value);
/****************************************************************************
* Name: tiff_putstring
*
* Description:
* Write a string of fixed length to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* string - A pointer to the memory containing the string
* len - The length of the string (including the NUL terminator)
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
EXTERN int tiff_putstring(int fd, FAR const char *string, int len);
/****************************************************************************
* Name: tiff_wordalign
*
* Description:
* Pad a file with zeros as necessary to achieve word alignament.
*
* Input Parameters:
* fd - File descriptor to be used.
* size - The current size of the file
*
* Returned Value:
* The new size of the file on success. A negated errno value on failure.
*
****************************************************************************/
EXTERN ssize_t tiff_wordalign(int fd, size_t size);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __APPS_GRAPHICS_TIFF_TIFF_INTERNAL_H */
+381
View File
@@ -0,0 +1,381 @@
/****************************************************************************
* apps/graphics/tiff/tiff_utils.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <apps/tiff.h>
#include "tiff_internal.h"
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiff_put/get16/32
*
* Description:
* Put and get 16 and 32 values in the correct byte order at the specified
* position.
*
* Input Parameters:
* dest - The location to store the multi-byte data (put only)
* src - The location to get the multi-byte data (get only)
* value - The value to be stored (put only)
*
* Returned Value:
* None (put)
* The extracted value (get)
*
****************************************************************************/
void tiff_put16(FAR uint8_t *dest, uint16_t value)
{
#ifdef CONFIG_ENDIAN_BIG
*dest++ = (uint8_t)(value >> 8);
*dest = (uint8_t)(value & 0xff);
#else
*dest++ = (uint8_t)(value & 0xff);
*dest = (uint8_t)(value >> 8);
#endif
}
void tiff_put32(FAR uint8_t *dest, uint32_t value)
{
#ifdef CONFIG_ENDIAN_BIG
tiff_put16(dest, (uint16_t)(value >> 16));
tiff_put16(dest+2, (uint16_t)(value & 0xffff));
#else
tiff_put16(dest, (uint16_t)(value & 0xffff));
tiff_put16(dest+2, (uint16_t)(value >> 16));
#endif
}
uint16_t tiff_get16(FAR uint8_t *src)
{
#ifdef CONFIG_ENDIAN_BIG
return (uint16_t)src[0] << 8 | (uint16_t)src[1];
#else
return (uint16_t)src[1] << 8 | (uint16_t)src[0];
#endif
}
uint32_t tiff_get32(FAR uint8_t *src)
{
#ifdef CONFIG_ENDIAN_BIG
return (uint32_t)tiff_get16(src) << 16 | (uint32_t)tiff_get16(src+2);
#else
return (uint32_t)tiff_get16(src+2) << 16 | (uint32_t)tiff_get16(src);
#endif
}
/****************************************************************************
* Name: tiff_read
*
* Description:
* Read TIFF data from the specified file
*
* Input Parameters:
* fd - Open file descriptor to read from
* buffer - Read-only buffer containing the data to be written
* count - The number of bytes to write
*
* Returned Value:
* On success, then number of bytes read; Zero is returned on EOF.
* Otherwise, a negated errno value on failure.
*
****************************************************************************/
ssize_t tiff_read(int fd, FAR void *buffer, size_t count)
{
size_t ntotal;
ssize_t nbytes;
int errval;
/* This loop retries the write until either: (1) it completes successfully,
* or (2) until an irrecoverble error occurs.
*/
for (ntotal = 0; ntotal < count; )
{
/* Do the read. The number of bytes left to read is the total
* requested size (count) minus the amount that we have alread read
* (ntotal).
*/
nbytes = read(fd, buffer, count-ntotal);
/* Check for an error */
if (nbytes < 0)
{
/* EINTR is not an error.. this just means that the write was
* interrupted by a signal.
*/
errval = errno;
if (errval != EINTR)
{
/* Other errors are bad news and we will break out with an error */
return -errval;
}
}
/* Zero is a special case and means that the end of file was encountered. */
else if (nbytes == 0)
{
break;
}
/* What if read returns some number of bytes other than the requested number?
* This probably means that the end-of-file will be encountered the next time
* that we call read().
*/
else
{
buffer += nbytes;
ntotal += nbytes;
}
}
return ntotal;
}
/****************************************************************************
* Name: tiff_write
*
* Description:
* Write TIFF data to the specified file
*
* Input Parameters:
* fd - Open file descriptor to write to
* buffer - Read-only buffer containing the data to be written
* count - The number of bytes to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_write(int fd, FAR const void *buffer, size_t count)
{
ssize_t nbytes;
int errval;
/* This loop retries the write until either: (1) it completes successfully,
* or (2) until an irrecoverble error occurs.
*/
while (count > 0)
{
/* Do the write */
nbytes = write(fd, buffer, count);
/* Check for an error */
if (nbytes < 0)
{
/* EINTR is not an error.. this just means that the write was
* interrupted by a signal.
*/
errval = errno;
if (errval != EINTR)
{
/* Other errors are bad news and we will break out with an error */
return -errval;
}
}
/* What if write returns some number of bytes other than the requested number? */
else
{
DEBUGASSERT(nbytes == count);
buffer += nbytes;
count -= nbytes;
}
}
return OK;
}
/****************************************************************************
* Name: tiff_putint16
*
* Description:
* Write two bytes to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* value - The 2-byte, uint16_t value to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_putint16(int fd, uint16_t value)
{
uint8_t bytes[2];
/* Write the two bytes to the output file */
tiff_put16(bytes, value);
return tiff_write(fd, bytes, 2);
}
/****************************************************************************
* Name: tiff_putint32
*
* Description:
* Write four bytes to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* value - The 4-byte, uint32_t value to write
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_putint32(int fd, uint32_t value)
{
uint8_t bytes[4];
/* Write the four bytes to the output file */
tiff_put32(bytes, value);
return tiff_write(fd, bytes, 4);
}
/****************************************************************************
* Name: tiff_putstring
*
* Description:
* Write a string of fixed length to the outfile.
*
* Input Parameters:
* fd - File descriptor to be used.
* string - A pointer to the memory containing the string
* len - The length of the string (including the NUL terminator)
*
* Returned Value:
* Zero (OK) on success. A negated errno value on failure.
*
****************************************************************************/
int tiff_putstring(int fd, FAR const char *string, int len)
{
#ifdef CONFIG_DEBUG_GRAPHICS
int actual = strlen(string);
ASSERT(len = actual+1);
#endif
return tiff_write(fd, string, len);
}
/****************************************************************************
* Name: tiff_wordalign
*
* Description:
* Pad a file with zeros as necessary to achieve word alignament.
*
* Input Parameters:
* fd - File descriptor to be used.
* size - The current size of the file
*
* Returned Value:
* The new size of the file on success. A negated errno value on failure.
*
****************************************************************************/
ssize_t tiff_wordalign(int fd, size_t size)
{
unsigned int remainder;
int ret;
remainder = size & 3;
if (remainder > 0)
{
unsigned int nbytes = 4 - remainder;
uint32_t value = 0;
ret = tiff_write(fd, &value, nbytes);
if (ret < 0)
{
return (ssize_t)ret;
}
size += nbytes;
}
return size;
}