Wrote a small test program that can reproduce the problem in bug #2206.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25446 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -26,3 +26,5 @@ UnitTestLib libtranslatorstest.so
|
|||||||
TIFFTranslatorTest.cpp
|
TIFFTranslatorTest.cpp
|
||||||
: $(libtranslation) be $(TARGET_LIBSTDC++)
|
: $(libtranslation) be $(TARGET_LIBSTDC++)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SubInclude HAIKU_TOP src tests add-ons translators exif ;
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
SubDir HAIKU_TOP src tests add-ons translators exif ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
SubDirSysHdrs [ FDirName $(HAIKU_TOP) src add-ons translators jpeg ] ;
|
||||||
|
SubDirSysHdrs [ FDirName $(HAIKU_TOP) src add-ons translators raw ] ;
|
||||||
|
# for TIFF.h and ReadHelper.h
|
||||||
|
|
||||||
|
SimpleTest dump_exif :
|
||||||
|
dump_exif.cpp
|
||||||
|
exif_parser.cpp
|
||||||
|
|
||||||
|
: be
|
||||||
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles
|
||||||
|
exif_parser.cpp
|
||||||
|
] = [ FDirName $(HAIKU_TOP) src add-ons translators jpeg ] ;
|
||||||
|
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "exif_parser.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <BufferIO.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Message.h>
|
||||||
|
|
||||||
|
#include "ReadHelper.h"
|
||||||
|
#include "TIFF.h"
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
process_exif(uint8* data, uint32 length)
|
||||||
|
{
|
||||||
|
if (memcmp(data + 2, "Exif", 4))
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
BMemoryIO source(data + 8, length - 8);
|
||||||
|
BMessage exif;
|
||||||
|
status_t status = convert_exif_to_message(source, exif);
|
||||||
|
if (status == B_OK)
|
||||||
|
exif.PrintToStream();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
process_jpeg(BPositionIO& stream)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
START_OF_IMAGE_MARKER = 0xd8,
|
||||||
|
EXIF_MARKER = 0xe1
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 header[2];
|
||||||
|
if (stream.Read(&header, 2) != 2)
|
||||||
|
return B_IO_ERROR;
|
||||||
|
if (header[0] != 0xff || header[1] != START_OF_IMAGE_MARKER)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// read marker
|
||||||
|
uint8 marker;
|
||||||
|
for (int32 i = 0; i < 7; i++) {
|
||||||
|
if (stream.Read(&marker, 1) != 1)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
if (marker != 0xff)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (marker == 0xff)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
// get length of section
|
||||||
|
|
||||||
|
uint16 length;
|
||||||
|
if (stream.Read(&length, 2) != 2)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
swap_data(B_UINT16_TYPE, &length, 2, B_SWAP_BENDIAN_TO_HOST);
|
||||||
|
|
||||||
|
if (marker == EXIF_MARKER) {
|
||||||
|
// read in section
|
||||||
|
stream.Seek(-2, SEEK_CUR);
|
||||||
|
|
||||||
|
uint8 exifData[length];
|
||||||
|
if (stream.Read(exifData, length) == length
|
||||||
|
&& process_exif(exifData, length) == B_OK)
|
||||||
|
return B_OK;
|
||||||
|
} else {
|
||||||
|
// ignore section
|
||||||
|
stream.Seek(length - 2, SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
process_file(entry_ref& ref)
|
||||||
|
{
|
||||||
|
BFile file(&ref, B_READ_WRITE);
|
||||||
|
status_t status = file.InitCheck();
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// read EXIF
|
||||||
|
|
||||||
|
BBufferIO stream(&file, 65536, false);
|
||||||
|
status = process_jpeg(file);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "%s: processing JPEG file failed: %s\n", ref.name,
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
BEntry entry(argv[i]);
|
||||||
|
entry_ref ref;
|
||||||
|
if (entry.InitCheck() != B_OK || entry.GetRef(&ref) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
process_file(ref);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user