TIFF library now passes its unit test
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3970 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
d37e2a8023
commit
ca15acf7a8
@ -111,4 +111,5 @@
|
||||
and command can be executed numerous times. Add a new verify command
|
||||
that will write to a register, read from register, and verify that
|
||||
returned value.
|
||||
* apps/graphics/tiff: Add a library that can be used to create TIFF files.
|
||||
* apps/graphics/tiff: Add a library that can be used to create TIFF files.
|
||||
* apps/examples/tiff: Add a unit test for the TIFF file creation logic
|
||||
|
@ -735,10 +735,26 @@ examples/tiff
|
||||
|
||||
This is a simple unit test for the TIFF creation library at apps/graphic/tiff.
|
||||
It is configured to work in the Linux user-mode simulation and has not been
|
||||
tested in any other environment.
|
||||
tested in any other environment. Since the example also depends on some
|
||||
other logic to mount a file system, currently it will only work as an NSH
|
||||
built-on, i.e., if the following is defined:
|
||||
|
||||
At a miniumum, you would probably have to change the hard-coded pathes to
|
||||
the TIFF files defined in the example to run in an embedded platform.
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_EXAMPLES_TIFF_BUILTIN=y
|
||||
|
||||
At a miniumum, to run in an embedded environment, you will probably have to
|
||||
change the configured paths to the TIFF files defined in the example.
|
||||
|
||||
CONFIG_EXAMPLES_TIFF_OUTFILE - Name of the resulting TIFF file. Default is
|
||||
"/tmp/result.tif"
|
||||
CONFIG_EXAMPLES_TIFF_TMPFILE1/2 - Names of two temporaries files that
|
||||
will be used in the file creation. Defaults are "/tmp/tmpfile1.dat" and
|
||||
"/tmp/tmpfile2.dat"
|
||||
|
||||
The following must also be defined in your appconfig file:
|
||||
|
||||
CONFIGURED_APPS += examples/tiff
|
||||
CONFIGURED_APPS += graphics/tiff
|
||||
|
||||
examples/udp
|
||||
^^^^^^^^^^^^
|
||||
|
@ -82,7 +82,7 @@ $(COBJS): %$(OBJEXT): %.c
|
||||
@touch .built
|
||||
|
||||
.context:
|
||||
ifeq ($(CONFIG_EXAMPLES_USBSTRG_BUILTIN),y)
|
||||
ifeq ($(CONFIG_EXAMPLES_TIFF_BUILTIN),y)
|
||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||
@touch $@
|
||||
endif
|
||||
|
@ -48,6 +48,34 @@
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* This is a simple unit test for the TIFF creation library at apps/graphic/tiff.
|
||||
* It is configured to work in the Linux user-mode simulation and has not been
|
||||
* tested in any other environment. Since the example also depends on some
|
||||
* other logic to mount a file system, currently it will only work as an NSH
|
||||
* built-on, i.e., if the following is defined:
|
||||
*
|
||||
* CONFIG_NSH_BUILTIN_APPS=y
|
||||
* CONFIG_EXAMPLES_TIFF_BUILTIN=y
|
||||
*
|
||||
* Other configuration options:
|
||||
*
|
||||
* CONFIG_EXAMPLES_TIFF_OUTFILE - Name of the resulting TIFF file
|
||||
* CONFIG_EXAMPLES_TIFF_TMPFILE1/2 - Names of two temporaries files that
|
||||
* will be used in the file creation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_TIFF_OUTFILE
|
||||
# define CONFIG_EXAMPLES_TIFF_OUTFILE "/tmp/result.tif"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_TIFF_TMPFILE1
|
||||
# define CONFIG_EXAMPLES_TIFF_TMPFILE1 "/tmp/tmpfile1.dat"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_TIFF_TMPFILE2
|
||||
# define CONFIG_EXAMPLES_TIFF_TMPFILE2 "/tmp/tmpfile2.dat"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -95,9 +123,9 @@ int MAIN_NAME(int argc, char *argv[])
|
||||
/* Configure the interface structure */
|
||||
|
||||
memset(&info, 0, sizeof(struct tiff_info_s));
|
||||
info.outfile = "result.tif";
|
||||
info.tmpfile1 = "tmpfile1.dat";
|
||||
info.tmpfile2 = "tmpfile2.dat";
|
||||
info.outfile = CONFIG_EXAMPLES_TIFF_OUTFILE;
|
||||
info.tmpfile1 = CONFIG_EXAMPLES_TIFF_TMPFILE1;
|
||||
info.tmpfile2 = CONFIG_EXAMPLES_TIFF_TMPFILE2;
|
||||
info.colorfmt = FB_FMT_RGB24;
|
||||
info.rps = 1;
|
||||
info.imgwidth = 256;
|
||||
@ -118,6 +146,7 @@ int MAIN_NAME(int argc, char *argv[])
|
||||
|
||||
for (green = 0, ptr = strip; green < 256; green++)
|
||||
{
|
||||
ptr = strip;
|
||||
for (blue = 0; blue < 256; blue++)
|
||||
{
|
||||
*ptr++ = (green + blue) >> 1;
|
||||
@ -138,7 +167,7 @@ int MAIN_NAME(int argc, char *argv[])
|
||||
ret = tiff_finalize(&info);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("tiff_initialize() failed: %d\n", ret);
|
||||
printf("tiff_finalize() failed: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
|
@ -144,7 +144,9 @@ int tiff_convstrip(FAR struct tiff_info_s *info, FAR const uint8_t *strip)
|
||||
/* Flush any buffer data to tmpfile2 */
|
||||
|
||||
ret = tiff_write(info->tmp2fd, info->iobuffer, nbytes);
|
||||
DEBUGASSERT(ntotal == info->bps);
|
||||
#ifdef CONFIG_DEBUG_GRAPHICS
|
||||
ASSERT(ntotal == info->bps);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -88,18 +88,22 @@ 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, SEEK_SET, offset);
|
||||
newoffs = lseek(fd, offset, SEEK_SET);
|
||||
if (newoffs == (off_t)-1)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Then read the IFD entry */
|
||||
/* Then read the IFD entry. Anything returned by tiff_read other than the
|
||||
* size of the IFD entry would be an error.
|
||||
*/
|
||||
|
||||
return tiff_read(fd, ifdentry, SIZEOF_IFD_ENTRY);
|
||||
nbytes = tiff_read(fd, ifdentry, SIZEOF_IFD_ENTRY);
|
||||
return nbytes == SIZEOF_IFD_ENTRY ? OK : -ENOSPC;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -125,7 +129,7 @@ static int tiff_writeifdentry(int fd, off_t offset,
|
||||
|
||||
/* Seek to the write position */
|
||||
|
||||
newoffs = lseek(fd, SEEK_SET, offset);
|
||||
newoffs = lseek(fd, offset, SEEK_SET);
|
||||
if (newoffs == (off_t)-1)
|
||||
{
|
||||
return -errno;
|
||||
@ -247,9 +251,9 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Seek to the beginning of tmpfile2 */
|
||||
/* Revind to the beginning of tmpfile1 */
|
||||
|
||||
offset = lseek(info->tmp2fd, SEEK_SET, 0);
|
||||
offset = lseek(info->tmp1fd, 0, SEEK_SET);
|
||||
if (offset == (off_t)-1)
|
||||
{
|
||||
ret = -errno;
|
||||
@ -258,14 +262,14 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
|
||||
/* Seek to the end of the outfile */
|
||||
|
||||
ret = lseek(info->outfd, SEEK_END, 0);
|
||||
ret = lseek(info->outfd, 0, SEEK_END);
|
||||
if (offset == (off_t)-1)
|
||||
{
|
||||
ret = -errno;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Now read strip offset data from tmpfile2, update the offsets, and write
|
||||
/* Now read strip offset data from tmpfile1, update the offsets, and write
|
||||
* the updated offsets to the outfile.
|
||||
*/
|
||||
|
||||
@ -277,6 +281,7 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
for (i = 0; i < info->nstrips; )
|
||||
{
|
||||
size_t noffsets;
|
||||
ssize_t nbytes;
|
||||
|
||||
/* Read a group of up to 32-bit values */
|
||||
|
||||
@ -286,8 +291,13 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
noffsets = maxoffsets;
|
||||
}
|
||||
|
||||
ret = tiff_read(info->tmp1fd, info->iobuffer, noffsets << 2);
|
||||
if (ret <= 0)
|
||||
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;
|
||||
}
|
||||
@ -305,7 +315,7 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
|
||||
/* Then write the corrected offsets to the outfile */
|
||||
|
||||
ret = tiff_write(info->outfd, info->iobuffer, noffsets << 2);
|
||||
ret = tiff_write(info->outfd, info->iobuffer, nbytes);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
@ -315,14 +325,22 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
|
||||
i += noffsets;
|
||||
#ifdef CONFIG_DEBUG_GRAPHICS
|
||||
total += noffsets << 2;
|
||||
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
|
||||
@ -335,12 +353,15 @@ int tiff_finalize(FAR struct tiff_info_s *info)
|
||||
/* 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 (ret == 0)
|
||||
else if (nbytes == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -635,11 +635,11 @@ int tiff_initialize(FAR struct tiff_info_s *info)
|
||||
|
||||
if (IMGFLAGS_ISRGB(info->imgflags))
|
||||
{
|
||||
val16 = TAG_PMI_BLACK;
|
||||
val16 = TAG_PMI_RGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
val16 = TAG_PMI_RGB;
|
||||
val16 = TAG_PMI_BLACK;
|
||||
}
|
||||
|
||||
ret = tiff_putifdentry16(info, IFD_TAG_PMI, IFD_FIELD_SHORT, 1, val16);
|
||||
@ -750,7 +750,6 @@ int tiff_initialize(FAR struct tiff_info_s *info)
|
||||
* RGB: Offset 168 Count, Hard-coded "NuttX"
|
||||
*/
|
||||
|
||||
tiff_checkoffs(offset, info->filefmt->sbcifdoffset);
|
||||
ret = tiff_putifdentry(info, IFD_TAG_SOFTWARE, IFD_FIELD_ASCII, TIFF_SOFTWARE_STRLEN, info->filefmt->swoffset);
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -765,7 +764,6 @@ int tiff_initialize(FAR struct tiff_info_s *info)
|
||||
* RGB: Offset 180 Count, Format "YYYY:MM:DD HH:MM:SS"
|
||||
*/
|
||||
|
||||
tiff_checkoffs(offset, info->filefmt->sbcifdoffset);
|
||||
ret = tiff_putifdentry(info, IFD_TAG_DATETIME, IFD_FIELD_ASCII, TIFF_DATETIME_STRLEN, info->filefmt->dateoffset);
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -830,6 +828,24 @@ int tiff_initialize(FAR struct tiff_info_s *info)
|
||||
}
|
||||
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:
|
||||
*
|
||||
*
|
||||
@ -838,7 +854,7 @@ int tiff_initialize(FAR struct tiff_info_s *info)
|
||||
* RGB: Offset 220, Hard-coded "NuttX"
|
||||
*/
|
||||
|
||||
tiff_checkoffs(offset, info->filefmt->xresoffset);
|
||||
tiff_checkoffs(offset, info->filefmt->swoffset);
|
||||
ret = tiff_putstring(info->outfd, TIFF_SOFTWARE_STRING, TIFF_SOFTWARE_STRLEN);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -108,11 +108,12 @@ extern "C" {
|
||||
* count - The number of bytes to write
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
* On success, then number of bytes read; Zero is returned on EOF.
|
||||
* Otherwise, a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int tiff_read(int fd, FAR void *buffer, size_t count);
|
||||
EXTERN ssize_t tiff_read(int fd, FAR void *buffer, size_t count);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tiff_write
|
||||
|
@ -144,12 +144,14 @@ uint32_t tiff_get32(FAR uint8_t *src)
|
||||
* count - The number of bytes to write
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
* On success, then number of bytes read; Zero is returned on EOF.
|
||||
* Otherwise, a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tiff_read(int fd, FAR void *buffer, size_t count)
|
||||
ssize_t tiff_read(int fd, FAR void *buffer, size_t count)
|
||||
{
|
||||
size_t ntotal;
|
||||
ssize_t nbytes;
|
||||
int errval;
|
||||
|
||||
@ -157,11 +159,14 @@ int tiff_read(int fd, FAR void *buffer, size_t count)
|
||||
* or (2) until an irrecoverble error occurs.
|
||||
*/
|
||||
|
||||
while (count > 0)
|
||||
for (ntotal = 0; ntotal < count; )
|
||||
{
|
||||
/* Do the read */
|
||||
/* 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);
|
||||
nbytes = read(fd, buffer, count-ntotal);
|
||||
|
||||
/* Check for an error */
|
||||
|
||||
@ -180,17 +185,26 @@ int tiff_read(int fd, FAR void *buffer, size_t count)
|
||||
}
|
||||
}
|
||||
|
||||
/* What if read returns some number of bytes other than the requested number? */
|
||||
/* 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
|
||||
{
|
||||
DEBUGASSERT(nbytes < count && nbytes != 0);
|
||||
buffer += nbytes;
|
||||
count -= nbytes;
|
||||
ntotal += nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return ntotal;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -245,7 +259,7 @@ int tiff_write(int fd, FAR const void *buffer, size_t count)
|
||||
|
||||
else
|
||||
{
|
||||
DEBUGASSERT(nbytes < count && nbytes != 0);
|
||||
DEBUGASSERT(nbytes == count);
|
||||
buffer += nbytes;
|
||||
count -= nbytes;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user