Deleted unused libraries Qmeta and jhead

This commit is contained in:
Paolo Cignoni cignoni 2010-11-25 13:09:15 +00:00
parent 496b0bfe4a
commit 9e5063193b
43 changed files with 464 additions and 6252 deletions

View File

@ -0,0 +1,291 @@
#############################################################################
# Makefile for building: libfilter_photosynth.dylib
# Generated by qmake (2.01a) (Qt 4.7.0) on: Tue Nov 23 16:55:56 2010
# Project: filter_photosynth.pro
# Template: lib
# Command: /usr/bin/qmake -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile filter_photosynth.pro
#############################################################################
####### Compiler, tools and options
CC = gcc
CXX = g++-4.2
DEFINES = -DQT_PLUGIN -DQT_SCRIPT_LIB -DQT_XMLPATTERNS_LIB -DQT_XML_LIB -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS = -pipe -g -gdwarf-2 -Wall -W -fPIC $(DEFINES)
CXXFLAGS = -pipe -g -gdwarf-2 -Wall -W -fPIC $(DEFINES)
INCPATH = -I/usr/local/Qt4.7/mkspecs/macx-g++ -I. -I/Library/Frameworks/QtCore.framework/Versions/4/Headers -I/usr/include/QtCore -I/Library/Frameworks/QtNetwork.framework/Versions/4/Headers -I/usr/include/QtNetwork -I/Library/Frameworks/QtGui.framework/Versions/4/Headers -I/usr/include/QtGui -I/Library/Frameworks/QtOpenGL.framework/Versions/4/Headers -I/usr/include/QtOpenGL -I/Library/Frameworks/QtXml.framework/Versions/4/Headers -I/usr/include/QtXml -I/Library/Frameworks/QtXmlPatterns.framework/Versions/4/Headers -I/usr/include/QtXmlPatterns -I/Library/Frameworks/QtScript.framework/Versions/4/Headers -I/usr/include/QtScript -I/usr/include -I../.. -I../../../../vcglib -I../../external/glew-1.5.1/include -I../../external/qtsoap-2.7_1/src -I/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers -I/System/Library/Frameworks/AGL.framework/Headers -I. -F/Library/Frameworks
LINK = g++
LFLAGS = -headerpad_max_install_names -single_module -dynamiclib
LIBS = $(SUBLIBS) -F/Library/Frameworks -L/Library/Frameworks ../../common/libcommon.dylib -framework QtScript -L/tmp/qt-stuff-6474/source/qt-everywhere-opensource-src-4.7.0/lib -F/tmp/qt-stuff-6474/source/qt-everywhere-opensource-src-4.7.0/lib -framework QtXmlPatterns -framework QtXml -framework QtOpenGL -framework QtGui -framework QtNetwork -framework QtCore -framework OpenGL -framework AGL
AR = ar cq
RANLIB = ranlib -s
QMAKE = /usr/bin/qmake
TAR = tar -cf
COMPRESS = gzip -9f
COPY = cp -f
SED = sed
COPY_FILE = cp -f
COPY_DIR = cp -f -R
STRIP =
INSTALL_FILE = $(COPY_FILE)
INSTALL_DIR = $(COPY_DIR)
INSTALL_PROGRAM = $(COPY_FILE)
DEL_FILE = rm -f
SYMLINK = ln -f -s
DEL_DIR = rmdir
MOVE = mv -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
export MACOSX_DEPLOYMENT_TARGET = 10.4
####### Output directory
OBJECTS_DIR = ./
####### Files
SOURCES = filter_photosynth.cpp \
downloader.cpp \
../../external/qtsoap-2.7_1/src/qtsoap.cpp moc_filter_photosynth.cpp \
moc_synthData.cpp \
moc_qtsoap.cpp
OBJECTS = filter_photosynth.o \
downloader.o \
qtsoap.o \
moc_filter_photosynth.o \
moc_synthData.o \
moc_qtsoap.o
DIST = /usr/local/Qt4.7/mkspecs/common/unix.conf \
/usr/local/Qt4.7/mkspecs/common/mac.conf \
/usr/local/Qt4.7/mkspecs/common/mac-g++.conf \
/usr/local/Qt4.7/mkspecs/qconfig.pri \
/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri \
/usr/local/Qt4.7/mkspecs/features/qt_functions.prf \
/usr/local/Qt4.7/mkspecs/features/qt_config.prf \
/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf \
/usr/local/Qt4.7/mkspecs/features/default_pre.prf \
/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf \
../../shared.pri \
/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf \
/usr/local/Qt4.7/mkspecs/features/debug.prf \
/usr/local/Qt4.7/mkspecs/features/default_post.prf \
/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf \
/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf \
/usr/local/Qt4.7/mkspecs/features/warn_on.prf \
/usr/local/Qt4.7/mkspecs/features/qt.prf \
/usr/local/Qt4.7/mkspecs/features/unix/opengl.prf \
/usr/local/Qt4.7/mkspecs/features/unix/thread.prf \
/usr/local/Qt4.7/mkspecs/features/moc.prf \
/usr/local/Qt4.7/mkspecs/features/mac/rez.prf \
/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf \
/usr/local/Qt4.7/mkspecs/features/resources.prf \
/usr/local/Qt4.7/mkspecs/features/uic.prf \
/usr/local/Qt4.7/mkspecs/features/yacc.prf \
/usr/local/Qt4.7/mkspecs/features/lex.prf \
/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf \
filter_photosynth.pro
QMAKE_TARGET = filter_photosynth
DESTDIR = ../../distrib/plugins/
TARGET = libfilter_photosynth.dylib
TARGETD = libfilter_photosynth.dylib
####### Custom Compiler Variables
QMAKE_COMP_QMAKE_OBJECTIVE_CFLAGS = -pipe \
-g \
-gdwarf-2 \
-Wall \
-W
first: all
####### Implicit rules
.SUFFIXES: .o .c .cpp .cc .cxx .C
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.cc.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.C.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.c.o:
$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
####### Build rules
all: Makefile ../../distrib/plugins/$(TARGET)
../../distrib/plugins/$(TARGET): $(OBJECTS) $(SUBLIBS) $(OBJCOMP)
@$(CHK_DIR_EXISTS) ../../distrib/plugins/ || $(MKDIR) ../../distrib/plugins/
-$(DEL_FILE) $(TARGET)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP)
-$(MOVE) $(TARGET) ../../distrib/plugins/
Makefile: filter_photosynth.pro /usr/local/Qt4.7/mkspecs/macx-g++/qmake.conf /usr/local/Qt4.7/mkspecs/common/unix.conf \
/usr/local/Qt4.7/mkspecs/common/mac.conf \
/usr/local/Qt4.7/mkspecs/common/mac-g++.conf \
/usr/local/Qt4.7/mkspecs/qconfig.pri \
/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri \
/usr/local/Qt4.7/mkspecs/features/qt_functions.prf \
/usr/local/Qt4.7/mkspecs/features/qt_config.prf \
/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf \
/usr/local/Qt4.7/mkspecs/features/default_pre.prf \
/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf \
../../shared.pri \
/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf \
/usr/local/Qt4.7/mkspecs/features/debug.prf \
/usr/local/Qt4.7/mkspecs/features/default_post.prf \
/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf \
/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf \
/usr/local/Qt4.7/mkspecs/features/warn_on.prf \
/usr/local/Qt4.7/mkspecs/features/qt.prf \
/usr/local/Qt4.7/mkspecs/features/unix/opengl.prf \
/usr/local/Qt4.7/mkspecs/features/unix/thread.prf \
/usr/local/Qt4.7/mkspecs/features/moc.prf \
/usr/local/Qt4.7/mkspecs/features/mac/rez.prf \
/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf \
/usr/local/Qt4.7/mkspecs/features/resources.prf \
/usr/local/Qt4.7/mkspecs/features/uic.prf \
/usr/local/Qt4.7/mkspecs/features/yacc.prf \
/usr/local/Qt4.7/mkspecs/features/lex.prf \
/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf \
/Library/Frameworks/QtScript.framework/QtScript.prl \
/Library/Frameworks/QtCore.framework/QtCore.prl \
/Library/Frameworks/QtXmlPatterns.framework/QtXmlPatterns.prl \
/Library/Frameworks/QtNetwork.framework/QtNetwork.prl \
/Library/Frameworks/QtXml.framework/QtXml.prl \
/Library/Frameworks/QtOpenGL.framework/QtOpenGL.prl \
/Library/Frameworks/QtGui.framework/QtGui.prl
$(QMAKE) -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile filter_photosynth.pro
/usr/local/Qt4.7/mkspecs/common/unix.conf:
/usr/local/Qt4.7/mkspecs/common/mac.conf:
/usr/local/Qt4.7/mkspecs/common/mac-g++.conf:
/usr/local/Qt4.7/mkspecs/qconfig.pri:
/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri:
/usr/local/Qt4.7/mkspecs/features/qt_functions.prf:
/usr/local/Qt4.7/mkspecs/features/qt_config.prf:
/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf:
/usr/local/Qt4.7/mkspecs/features/default_pre.prf:
/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf:
../../shared.pri:
/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf:
/usr/local/Qt4.7/mkspecs/features/debug.prf:
/usr/local/Qt4.7/mkspecs/features/default_post.prf:
/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf:
/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf:
/usr/local/Qt4.7/mkspecs/features/warn_on.prf:
/usr/local/Qt4.7/mkspecs/features/qt.prf:
/usr/local/Qt4.7/mkspecs/features/unix/opengl.prf:
/usr/local/Qt4.7/mkspecs/features/unix/thread.prf:
/usr/local/Qt4.7/mkspecs/features/moc.prf:
/usr/local/Qt4.7/mkspecs/features/mac/rez.prf:
/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf:
/usr/local/Qt4.7/mkspecs/features/resources.prf:
/usr/local/Qt4.7/mkspecs/features/uic.prf:
/usr/local/Qt4.7/mkspecs/features/yacc.prf:
/usr/local/Qt4.7/mkspecs/features/lex.prf:
/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf:
/Library/Frameworks/QtScript.framework/QtScript.prl:
/Library/Frameworks/QtCore.framework/QtCore.prl:
/Library/Frameworks/QtXmlPatterns.framework/QtXmlPatterns.prl:
/Library/Frameworks/QtNetwork.framework/QtNetwork.prl:
/Library/Frameworks/QtXml.framework/QtXml.prl:
/Library/Frameworks/QtOpenGL.framework/QtOpenGL.prl:
/Library/Frameworks/QtGui.framework/QtGui.prl:
qmake: FORCE
@$(QMAKE) -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile filter_photosynth.pro
dist:
@$(CHK_DIR_EXISTS) .tmp/filter_photosynth1.0.0 || $(MKDIR) .tmp/filter_photosynth1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/filter_photosynth1.0.0/ && $(COPY_FILE) --parents filter_photosynth.h synthData.h ../../external/qtsoap-2.7_1/src/qtsoap.h .tmp/filter_photosynth1.0.0/ && $(COPY_FILE) --parents filter_photosynth.cpp downloader.cpp ../../external/qtsoap-2.7_1/src/qtsoap.cpp .tmp/filter_photosynth1.0.0/ && (cd `dirname .tmp/filter_photosynth1.0.0` && $(TAR) filter_photosynth1.0.0.tar filter_photosynth1.0.0 && $(COMPRESS) filter_photosynth1.0.0.tar) && $(MOVE) `dirname .tmp/filter_photosynth1.0.0`/filter_photosynth1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/filter_photosynth1.0.0
clean:compiler_clean
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) *~ core *.core
####### Sub-libraries
distclean: clean
-$(DEL_FILE) $(TARGET)
-$(DEL_FILE) Makefile
check: first
mocclean: compiler_moc_header_clean compiler_moc_source_clean
mocables: compiler_moc_header_make_all compiler_moc_source_make_all
compiler_objective_c_make_all:
compiler_objective_c_clean:
compiler_moc_header_make_all: moc_filter_photosynth.cpp moc_synthData.cpp moc_qtsoap.cpp
compiler_moc_header_clean:
-$(DEL_FILE) moc_filter_photosynth.cpp moc_synthData.cpp moc_qtsoap.cpp
moc_filter_photosynth.cpp: synthData.h \
filter_photosynth.h
/Developer/Tools/Qt/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ filter_photosynth.h -o moc_filter_photosynth.cpp
moc_synthData.cpp: synthData.h
/Developer/Tools/Qt/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ synthData.h -o moc_synthData.cpp
moc_qtsoap.cpp: ../../external/qtsoap-2.7_1/src/qtsoap.h
/Developer/Tools/Qt/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ ../../external/qtsoap-2.7_1/src/qtsoap.h -o moc_qtsoap.cpp
compiler_rcc_make_all:
compiler_rcc_clean:
compiler_image_collection_make_all: qmake_image_collection.cpp
compiler_image_collection_clean:
-$(DEL_FILE) qmake_image_collection.cpp
compiler_moc_source_make_all:
compiler_moc_source_clean:
compiler_rez_source_make_all:
compiler_rez_source_clean:
compiler_uic_make_all:
compiler_uic_clean:
compiler_yacc_decl_make_all:
compiler_yacc_decl_clean:
compiler_yacc_impl_make_all:
compiler_yacc_impl_clean:
compiler_lex_make_all:
compiler_lex_clean:
compiler_clean: compiler_moc_header_clean
####### Compile
filter_photosynth.o: filter_photosynth.cpp filter_photosynth.h \
synthData.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o filter_photosynth.o filter_photosynth.cpp
downloader.o: downloader.cpp synthData.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o downloader.o downloader.cpp
qtsoap.o: ../../external/qtsoap-2.7_1/src/qtsoap.cpp ../../external/qtsoap-2.7_1/src/qtsoap.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o qtsoap.o ../../external/qtsoap-2.7_1/src/qtsoap.cpp
moc_filter_photosynth.o: moc_filter_photosynth.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_filter_photosynth.o moc_filter_photosynth.cpp
moc_synthData.o: moc_synthData.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_synthData.o moc_synthData.cpp
moc_qtsoap.o: moc_qtsoap.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_qtsoap.o moc_qtsoap.cpp
####### Install
install: FORCE
uninstall: FORCE
FORCE:

File diff suppressed because it is too large Load Diff

View File

@ -1,217 +0,0 @@
//--------------------------------------------------------------------------
// Parsing of GPS info from exif header.
//
// Matthias Wandel, Dec 1999 - Dec 2002
//--------------------------------------------------------------------------
#include "jhead.h"
#define MAX_GPS_TAG 0x1e
#define TAG_GPS_LAT_REF 1
#define TAG_GPS_LAT 2
#define TAG_GPS_LONG_REF 3
#define TAG_GPS_LONG 4
#define TAG_GPS_ALT_REF 5
#define TAG_GPS_ALT 6
static const char * GpsTags[MAX_GPS_TAG+1]= {
"VersionID ",//0x00
"LatitudeRef ",//0x01
"Latitude ",//0x02
"LongitudeRef ",//0x03
"Longitude ",//0x04
"AltitudeRef ",//0x05
"Altitude ",//0x06
"TimeStamp ",//0x07
"Satellites ",//0x08
"Status ",//0x09
"MeasureMode ",//0x0A
"DOP ",//0x0B
"SpeedRef ",//0x0C
"Speed ",//0x0D
"TrackRef ",//0x0E
"Track ",//0x0F
"ImgDirectionRef ",//0x10
"ImgDirection ",//0x11
"MapDatum ",//0x12
"DestLatitudeRef ",//0x13
"DestLatitude ",//0x14
"DestLongitudeRef",//0x15
"DestLongitude ",//0x16
"DestBearingRef ",//0x17
"DestBearing ",//0x18
"DestDistanceRef ",//0x19
"DestDistance ",//0x1A
"ProcessingMethod",//0x1B
"AreaInformation ",//0x1C
"DateStamp ",//0x1D
"Differential ",//0x1E
};
//--------------------------------------------------------------------------
// Process GPS info directory
//--------------------------------------------------------------------------
void ProcessGpsInfo(unsigned char * DirStart, int ByteCountUnused, unsigned char * OffsetBase, unsigned ExifLength)
{
int de;
unsigned a;
int NumDirEntries;
NumDirEntries = Get16u(DirStart);
#define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
if (ShowTags){
printf("(dir has %d entries)\n",NumDirEntries);
}
ImageInfo.GpsInfoPresent = TRUE;
strcpy(ImageInfo.GpsLat, "? ?");
strcpy(ImageInfo.GpsLong, "? ?");
ImageInfo.GpsAlt[0] = 0;
for (de=0;de<NumDirEntries;de++){
unsigned Tag, Format, Components;
unsigned char * ValuePtr;
int ComponentSize;
unsigned ByteCount;
unsigned char * DirEntry;
DirEntry = DIR_ENTRY_ADDR(DirStart, de);
if (DirEntry+12 > OffsetBase+ExifLength){
ErrNonfatal("GPS info directory goes past end of exif",0,0);
return;
}
Tag = Get16u(DirEntry);
Format = Get16u(DirEntry+2);
Components = Get32u(DirEntry+4);
if ((Format-1) >= NUM_FORMATS) {
// (-1) catches illegal zero case as unsigned underflows to positive large.
ErrNonfatal("Illegal number format %d for Exif gps tag %04x", Format, Tag);
continue;
}
ComponentSize = BytesPerFormat[Format];
ByteCount = Components * ComponentSize;
if (ByteCount > 4){
unsigned OffsetVal;
OffsetVal = Get32u(DirEntry+8);
// If its bigger than 4 bytes, the dir entry contains an offset.
if (OffsetVal+ByteCount > ExifLength){
// Bogus pointer offset and / or bytecount value
ErrNonfatal("Illegal value pointer for Exif gps tag %04x", Tag,0);
continue;
}
ValuePtr = OffsetBase+OffsetVal;
}else{
// 4 bytes or less and value is in the dir entry itself
ValuePtr = DirEntry+8;
}
switch(Tag){
char FmtString[21];
char TempString[50];
double Values[3];
case TAG_GPS_LAT_REF:
ImageInfo.GpsLat[0] = ValuePtr[0];
break;
case TAG_GPS_LONG_REF:
ImageInfo.GpsLong[0] = ValuePtr[0];
break;
case TAG_GPS_LAT:
case TAG_GPS_LONG:
if (Format != FMT_URATIONAL){
ErrNonfatal("Inappropriate format (%d) for Exif GPS coordinates!", Format, 0);
}
strcpy(FmtString, "%0.0fd %0.0fm %0.0fs");
for (a=0;a<3;a++){
int den, digits;
den = Get32s(ValuePtr+4+a*ComponentSize);
digits = 0;
while (den > 1 && digits <= 6){
den = den / 10;
digits += 1;
}
if (digits > 6) digits = 6;
FmtString[1+a*7] = (char)('2'+digits+(digits ? 1 : 0));
FmtString[3+a*7] = (char)('0'+digits);
Values[a] = ConvertAnyFormat(ValuePtr+a*ComponentSize, Format);
}
sprintf(TempString, FmtString, Values[0], Values[1], Values[2]);
if (Tag == TAG_GPS_LAT){
strncpy(ImageInfo.GpsLat+2, TempString, 29);
}else{
strncpy(ImageInfo.GpsLong+2, TempString, 29);
}
break;
case TAG_GPS_ALT_REF:
ImageInfo.GpsAlt[0] = (char)(ValuePtr[0] ? '-' : ' ');
break;
case TAG_GPS_ALT:
sprintf(ImageInfo.GpsAlt + 1, "%.2fm",
ConvertAnyFormat(ValuePtr, Format));
break;
}
if (ShowTags){
// Show tag value.
if (Tag < MAX_GPS_TAG){
printf(" GPS%s =", GpsTags[Tag]);
}else{
// Show unknown tag
printf(" Illegal GPS tag %04x=", Tag);
}
switch(Format){
case FMT_UNDEFINED:
// Undefined is typically an ascii string.
case FMT_STRING:
// String arrays printed without function call (different from int arrays)
{
printf("\"");
for (a=0;a<ByteCount;a++){
int ZeroSkipped = 0;
if (ValuePtr[a] >= 32){
if (ZeroSkipped){
printf("?");
ZeroSkipped = 0;
}
putchar(ValuePtr[a]);
}else{
if (ValuePtr[a] == 0){
ZeroSkipped = 1;
}
}
}
printf("\"\n");
}
break;
default:
// Handle arrays of numbers later (will there ever be?)
for (a=0;;){
PrintFormatNumber(ValuePtr+a*ComponentSize, Format, ByteCount);
if (++a >= Components) break;
printf(", ");
}
printf("\n");
}
}
}
}

View File

@ -1,219 +0,0 @@
//--------------------------------------------------------------------------
// Process IPTC data and XMP data.
//--------------------------------------------------------------------------
#include "jhead.h"
// IPTC entry types known to Jhead (there's many more defined)
#define IPTC_RECORD_VERSION 0x00
#define IPTC_SUPLEMENTAL_CATEGORIES 0x14
#define IPTC_KEYWORDS 0x19
#define IPTC_CAPTION 0x78
#define IPTC_AUTHOR 0x7A
#define IPTC_HEADLINE 0x69
#define IPTC_SPECIAL_INSTRUCTIONS 0x28
#define IPTC_CATEGORY 0x0F
#define IPTC_BYLINE 0x50
#define IPTC_BYLINE_TITLE 0x55
#define IPTC_CREDIT 0x6E
#define IPTC_SOURCE 0x73
#define IPTC_COPYRIGHT_NOTICE 0x74
#define IPTC_OBJECT_NAME 0x05
#define IPTC_CITY 0x5A
#define IPTC_STATE 0x5F
#define IPTC_COUNTRY 0x65
#define IPTC_TRANSMISSION_REFERENCE 0x67
#define IPTC_DATE 0x37
#define IPTC_COPYRIGHT 0x0A
#define IPTC_COUNTRY_CODE 0x64
#define IPTC_REFERENCE_SERVICE 0x2D
#define IPTC_TIME_CREATED 0x3C
#define IPTC_SUB_LOCATION 0x5C
#define IPTC_IMAGE_TYPE 0x82
//--------------------------------------------------------------------------
// Process and display IPTC marker.
//
// IPTC block consists of:
// - Marker: 1 byte (0xED)
// - Block length: 2 bytes
// - IPTC Signature: 14 bytes ("Photoshop 3.0\0")
// - 8BIM Signature 4 bytes ("8BIM")
// - IPTC Block start 2 bytes (0x04, 0x04)
// - IPTC Header length 1 byte
// - IPTC header Header is padded to even length, counting the length byte
// - Length 4 bytes
// - IPTC Data which consists of a number of entries, each of which has the following format:
// - Signature 2 bytes (0x1C02)
// - Entry type 1 byte (for defined entry types, see #defines above)
// - entry length 2 bytes
// - entry data 'entry length' bytes
//
//--------------------------------------------------------------------------
void show_IPTC (unsigned char* Data, unsigned int itemlen)
{
const char IptcSig1[] = "Photoshop 3.0";
const char IptcSig2[] = "8BIM";
const char IptcSig3[] = {0x04, 0x04};
unsigned char * pos = Data + sizeof(short); // position data pointer after length field
unsigned char * maxpos = Data+itemlen;
unsigned char headerLen = 0;
unsigned char dataLen = 0;
if (itemlen < 25) goto corrupt;
// Check IPTC signatures
if (memcmp(pos, IptcSig1, sizeof(IptcSig1)-1) != 0) goto badsig;
pos += sizeof(IptcSig1); // move data pointer to the next field
if (memcmp(pos, IptcSig2, sizeof(IptcSig2)-1) != 0) goto badsig;
pos += sizeof(IptcSig2)-1; // move data pointer to the next field
while (memcmp(pos, IptcSig3, sizeof(IptcSig3)) != 0) { // loop on valid Photoshop blocks
pos += sizeof(IptcSig3); // move data pointer to the Header Length
// Skip header
headerLen = *pos; // get header length and move data pointer to the next field
pos += (headerLen & 0xfe) + 2; // move data pointer to the next field (Header is padded to even length, counting the length byte)
pos += 3; // move data pointer to length, assume only one byte, TODO: use all 4 bytes
dataLen = *pos++;
pos += dataLen; // skip data section
if (memcmp(pos, IptcSig2, sizeof(IptcSig2) - 1) != 0) {
badsig: if (ShowTags) {
ErrNonfatal("IPTC type signature mismatch\n", 0, 0);
}
return;
}
pos += sizeof(IptcSig2) - 1; // move data pointer to the next field
}
pos += sizeof(IptcSig3); // move data pointer to the next field
if (pos >= maxpos) goto corrupt;
// IPTC section found
// Skip header
headerLen = *pos++; // get header length and move data pointer to the next field
pos += headerLen + 1 - (headerLen % 2); // move data pointer to the next field (Header is padded to even length, counting the length byte)
if (pos+4 >= maxpos) goto corrupt;
// Get length (from motorola format)
//length = (*pos << 24) | (*(pos+1) << 16) | (*(pos+2) << 8) | *(pos+3);
pos += 4; // move data pointer to the next field
printf("======= IPTC data: =======\n");
// Now read IPTC data
while (pos < (Data + itemlen-5)) {
short signature;
unsigned char type = 0;
short length = 0;
char * description = NULL;
if (pos+5 > maxpos) goto corrupt;
signature = (*pos << 8) + (*(pos+1));
pos += 2;
if (signature != 0x1C01 && signature != 0x1c02) break;
type = *pos++;
length = (*pos << 8) + (*(pos+1));
pos += 2; // Skip tag length
if (pos+length > maxpos) goto corrupt;
// Process tag here
switch (type) {
case IPTC_RECORD_VERSION:
printf("Record vers. : %d\n", (*pos << 8) + (*(pos+1)));
break;
case IPTC_SUPLEMENTAL_CATEGORIES: description = "SuplementalCategories"; break;
case IPTC_KEYWORDS: description = "Keywords"; break;
case IPTC_CAPTION: description = "Caption"; break;
case IPTC_AUTHOR: description = "Author"; break;
case IPTC_HEADLINE: description = "Headline"; break;
case IPTC_SPECIAL_INSTRUCTIONS: description = "Spec. Instr."; break;
case IPTC_CATEGORY: description = "Category"; break;
case IPTC_BYLINE: description = "Byline"; break;
case IPTC_BYLINE_TITLE: description = "Byline Title"; break;
case IPTC_CREDIT: description = "Credit"; break;
case IPTC_SOURCE: description = "Source"; break;
case IPTC_COPYRIGHT_NOTICE: description = "(C)Notice"; break;
case IPTC_OBJECT_NAME: description = "Object Name"; break;
case IPTC_CITY: description = "City"; break;
case IPTC_STATE: description = "State"; break;
case IPTC_COUNTRY: description = "Country"; break;
case IPTC_TRANSMISSION_REFERENCE: description = "OriginalTransmissionReference"; break;
case IPTC_DATE: description = "DateCreated"; break;
case IPTC_COPYRIGHT: description = "(C)Flag"; break;
case IPTC_REFERENCE_SERVICE: description = "Country Code"; break;
case IPTC_COUNTRY_CODE: description = "Ref. Service"; break;
case IPTC_TIME_CREATED: description = "Time Created"; break;
case IPTC_SUB_LOCATION: description = "Sub Location"; break;
case IPTC_IMAGE_TYPE: description = "Image type"; break;
default:
if (ShowTags){
printf("Unrecognised IPTC tag: %d\n", type );
}
break;
}
if (description != NULL) {
char TempBuf[32];
memset(TempBuf, 0, sizeof(TempBuf));
memset(TempBuf, ' ', 14);
memcpy(TempBuf, description, strlen(description));
strcat(TempBuf, ":");
printf("%s %*.*s\n", TempBuf, length, length, pos);
}
pos += length;
}
return;
corrupt:
ErrNonfatal("Pointer corruption in IPTC\n",0,0);
}
//--------------------------------------------------------------------------
// Dump contents of XMP section
//--------------------------------------------------------------------------
void ShowXmp(Section_t XmpSection)
{
unsigned char * Data;
char OutLine[101];
int OutLineChars;
int NonBlank;
unsigned a;
NonBlank = 0;
Data = XmpSection.Data;
OutLineChars = 0;
for (a=0;a<XmpSection.Size;a++){
if (Data[a] >= 32 && Data[a] < 128){
OutLine[OutLineChars++] = Data[a];
if (Data[a] != ' ') NonBlank |= 1;
}else{
if (Data[a] != '\n'){
OutLine[OutLineChars++] = '?';
}
}
if (Data[a] == '\n' || OutLineChars >= 100){
OutLine[OutLineChars] = 0;
if (NonBlank){
puts(OutLine);
}
NonBlank = (NonBlank & 1) << 1;
OutLineChars = 0;
}
}
}

View File

@ -1,133 +0,0 @@
//--------------------------------------------------------------------------
// Program to pull the information out of various types of EXIF digital
// camera files and show it in a reasonably consistent way
//
// Version 2.90
//
// Compiling under Windows:
// Make sure you have Microsoft's compiler on the path, then run make.bat
//
// Dec 1999 - Feb 2010
//
// by Matthias Wandel www.sentex.net/~mwandel
//--------------------------------------------------------------------------
#include "jhead.h"
#include <sys/stat.h>
#define JHEAD_VERSION "2.90"
// This #define turns on features that are too very specific to
// how I organize my photos. Best to ignore everything inside #ifdef MATTHIAS
//#define MATTHIAS
#ifdef _WIN32
#include <io.h>
#endif
static int FilesMatched;
static int FileSequence;
static const char * CurrentFile;
static const char * progname; // program name for error messages
//--------------------------------------------------------------------------
// Command line options flags
static int TrimExif = FALSE; // Cut off exif beyond interesting data.
static int RenameToDate = 0; // 1=rename, 2=rename all.
#ifdef _WIN32
static int RenameAssociatedFiles = FALSE;
#endif
static char * strftime_args = NULL; // Format for new file name.
static int Exif2FileTime = FALSE;
static int DoModify = FALSE;
static int DoReadAction = FALSE;
int ShowTags = FALSE; // Do not show raw by default.
static int Quiet = FALSE; // Be quiet on success (like unix programs)
int DumpExifMap = FALSE;
static int ShowConcise = FALSE;
static int CreateExifSection = FALSE;
static char * ApplyCommand = NULL; // Apply this command to all images.
static char * FilterModel = NULL;
static int ExifOnly = FALSE;
static int PortraitOnly = FALSE;
static time_t ExifTimeAdjust = 0; // Timezone adjust
static time_t ExifTimeSet = 0; // Set exif time to a value.
static char DateSet[11];
static unsigned DateSetChars = 0;
static unsigned FileTimeToExif = FALSE;
static int DeleteComments = FALSE;
static int DeleteExif = FALSE;
static int DeleteIptc = FALSE;
static int DeleteXmp = FALSE;
static int DeleteUnknown = FALSE;
static char * ThumbSaveName = NULL; // If not NULL, use this string to make up
// the filename to store the thumbnail to.
static char * ThumbInsertName = NULL; // If not NULL, use this string to make up
// the filename to retrieve the thumbnail from.
static int RegenThumbnail = FALSE;
static char * ExifXferScrFile = NULL;// Extract Exif header from this file, and
// put it into the Jpegs processed.
static int EditComment = FALSE; // Invoke an editor for editing the comment
static int SupressNonFatalErrors = FALSE; // Wether or not to pint warnings on recoverable errors
static char * CommentSavefileName = NULL; // Save comment to this file.
static char * CommentInsertfileName = NULL; // Insert comment from this file.
static char * CommentInsertLiteral = NULL; // Insert this comment (from command line)
static int AutoRotate = FALSE;
static int ZeroRotateTagOnly = FALSE;
static int ShowFileInfo = TRUE; // Indicates to show standard file info
// (file name, file size, file date)
#ifdef MATTHIAS
// This #ifdef to take out less than elegant stuff for editing
// the comments in a JPEG. The programs rdjpgcom and wrjpgcom
// included with Linux distributions do a better job.
static char * AddComment = NULL; // Add this tag.
static char * RemComment = NULL; // Remove this tag
static int AutoResize = FALSE;
#endif // MATTHIAS
//--------------------------------------------------------------------------
// Error exit handler
//--------------------------------------------------------------------------
void ErrFatal(char * msg)
{
fprintf(stderr,"\nError : %s\n", msg);
if (CurrentFile) fprintf(stderr,"in file '%s'\n",CurrentFile);
exit(EXIT_FAILURE);
}
//--------------------------------------------------------------------------
// Report non fatal errors. Now that microsoft.net modifies exif headers,
// there's corrupted ones, and there could be more in the future.
//--------------------------------------------------------------------------
void ErrNonfatal(char * msg, int a1, int a2)
{
if (SupressNonFatalErrors) return;
fprintf(stderr,"\nNonfatal Error : ");
if (CurrentFile) fprintf(stderr,"'%s' ",CurrentFile);
fprintf(stderr, msg, a1, a2);
fprintf(stderr, "\n");
}
//--------------------------------------------------------------------------
// Set file time as exif time.
//--------------------------------------------------------------------------
void FileTimeAsString(char * TimeStr)
{
struct tm ts;
ts = *localtime(&ImageInfo.FileDateTime);
strftime(TimeStr, 20, "%Y:%m:%d %H:%M:%S", &ts);
}

View File

@ -1,254 +0,0 @@
//--------------------------------------------------------------------------
// Include file for jhead program.
//
// This include file only defines stuff that goes across modules.
// I like to keep the definitions for macros and structures as close to
// where they get used as possible, so include files only get stuff that
// gets used in more than one file.
//--------------------------------------------------------------------------
#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
//--------------------------------------------------------------------------
#ifdef _WIN32
#include <sys/utime.h>
#else
#include <utime.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#endif
typedef unsigned char uchar;
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define MAX_COMMENT_SIZE 2000
#ifdef _WIN32
#define JHEAD_PATH_MAX _MAX_PATH
#define SLASH '\\'
#else
#ifndef JHEAD_PATH_MAX
#define JHEAD_PATH_MAX 1024
#endif
#define SLASH '/'
#endif
//--------------------------------------------------------------------------
// This structure is used to store jpeg file sections in memory.
typedef struct {
uchar * Data;
int Type;
unsigned Size;
}Section_t;
extern int ExifSectionIndex;
extern int DumpExifMap;
#define MAX_DATE_COPIES 10
//--------------------------------------------------------------------------
// This structure stores Exif header image elements in a simple manner
// Used to store camera data as extracted from the various ways that it can be
// stored in an exif header
typedef struct {
char FileName [JHEAD_PATH_MAX+1];
time_t FileDateTime;
struct {
// Info in the jfif header.
// This info is not used much - jhead used to just replace it with default
// values, and over 10 years, only two people pointed this out.
char Present;
char ResolutionUnits;
short XDensity;
short YDensity;
}JfifHeader;
unsigned FileSize;
char CameraMake [32];
char CameraModel [40];
char DateTime [20];
int Height, Width;
int Orientation;
int IsColor;
int Process;
int FlashUsed;
float FocalLength;
float ExposureTime;
float ApertureFNumber;
float Distance;
float CCDWidth;
float ExposureBias;
float DigitalZoomRatio;
int FocalLength35mmEquiv; // Exif 2.2 tag - usually not present.
int Whitebalance;
int MeteringMode;
int ExposureProgram;
int ExposureMode;
int ISOequivalent;
int LightSource;
int DistanceRange;
float xResolution;
float yResolution;
int ResolutionUnit;
char Comments[MAX_COMMENT_SIZE];
int CommentWidthchars; // If nonzero, widechar comment, indicates number of chars.
unsigned ThumbnailOffset; // Exif offset to thumbnail
unsigned ThumbnailSize; // Size of thumbnail.
unsigned LargestExifOffset; // Last exif data referenced (to check if thumbnail is at end)
char ThumbnailAtEnd; // Exif header ends with the thumbnail
// (we can only modify the thumbnail if its at the end)
int ThumbnailSizeOffset;
int DateTimeOffsets[MAX_DATE_COPIES];
int numDateTimeTags;
int GpsInfoPresent;
char GpsLat[31];
char GpsLong[31];
char GpsAlt[20];
}ImageInfo_t;
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
// jpgfile.c functions
typedef enum {
READ_METADATA = 1,
READ_IMAGE = 2,
READ_ALL = 3
}ReadMode_t;
// prototypes for jhead.c functions
void ErrFatal(char * msg);
void ErrNonfatal(char * msg, int a1, int a2);
void FileTimeAsString(char * TimeStr);
// Prototypes for exif.c functions.
int Exif2tm(struct tm * timeptr, char * ExifTime);
void process_EXIF (unsigned char * CharBuf, unsigned int length);
int RemoveThumbnail(unsigned char * ExifSection);
void ShowImageInfo(int ShowFileInfo);
void ShowConciseImageInfo(void);
const char * ClearOrientation(void);
void PrintFormatNumber(void * ValuePtr, int Format, int ByteCount);
double ConvertAnyFormat(void * ValuePtr, int Format);
int Get16u(void * Short);
unsigned Get32u(void * Long);
int Get32s(void * Long);
void Put32u(void * Value, unsigned PutValue);
void create_EXIF(void);
//--------------------------------------------------------------------------
// Exif format descriptor stuff
extern const int BytesPerFormat[];
#define NUM_FORMATS 12
#define FMT_BYTE 1
#define FMT_STRING 2
#define FMT_USHORT 3
#define FMT_ULONG 4
#define FMT_URATIONAL 5
#define FMT_SBYTE 6
#define FMT_UNDEFINED 7
#define FMT_SSHORT 8
#define FMT_SLONG 9
#define FMT_SRATIONAL 10
#define FMT_SINGLE 11
#define FMT_DOUBLE 12
// makernote.c prototypes
extern void ProcessMakerNote(unsigned char * DirStart, int ByteCount,
unsigned char * OffsetBase, unsigned ExifLength);
// gpsinfo.c prototypes
void ProcessGpsInfo(unsigned char * ValuePtr, int ByteCount,
unsigned char * OffsetBase, unsigned ExifLength);
// iptc.c prototpyes
void show_IPTC (unsigned char * CharBuf, unsigned int length);
void ShowXmp(Section_t XmpSection);
// Prototypes for myglob.c module
#ifdef _WIN32
void MyGlob(const char * Pattern , void (*FileFuncParm)(const char * FileName));
void SlashToNative(char * Path);
#endif
// Prototypes for paths.c module
int EnsurePathExists(const char * FileName);
void CatPath(char * BasePath, const char * FilePath);
// Prototypes from jpgfile.c
int ReadJpegSections (FILE * infile, ReadMode_t ReadMode);
void DiscardData(void);
void DiscardAllButExif(void);
int ReadJpegFile(const char * FileName, ReadMode_t ReadMode);
int ReplaceThumbnail(const char * ThumbFileName);
int SaveThumbnail(char * ThumbFileName);
int RemoveSectionType(int SectionType);
int RemoveUnknownSections(void);
void WriteJpegFile(const char * FileName);
Section_t * FindSection(int SectionType);
Section_t * CreateSection(int SectionType, unsigned char * Data, int size);
void ResetJpgfile(void);
// Variables from jhead.c used by exif.c
extern ImageInfo_t ImageInfo;
extern int ShowTags;
//--------------------------------------------------------------------------
// JPEG markers consist of one or more 0xFF bytes, followed by a marker
// code byte (which is not an FF). Here are the marker codes of interest
// in this program. (See jdmarker.c for a more complete list.)
//--------------------------------------------------------------------------
#define M_SOF0 0xC0 // Start Of Frame N
#define M_SOF1 0xC1 // N indicates which compression process
#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
#define M_SOF3 0xC3
#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
#define M_SOF6 0xC6
#define M_SOF7 0xC7
#define M_SOF9 0xC9
#define M_SOF10 0xCA
#define M_SOF11 0xCB
#define M_SOF13 0xCD
#define M_SOF14 0xCE
#define M_SOF15 0xCF
#define M_SOI 0xD8 // Start Of Image (beginning of datastream)
#define M_EOI 0xD9 // End Of Image (end of datastream)
#define M_SOS 0xDA // Start Of Scan (begins compressed data)
#define M_JFIF 0xE0 // Jfif marker
#define M_EXIF 0xE1 // Exif marker. Also used for XMP data!
#define M_XMP 0x10E1 // Not a real tag (same value in file as Exif!)
#define M_COM 0xFE // COMment
#define M_DQT 0xDB
#define M_DHT 0xC4
#define M_DRI 0xDD
#define M_IPTC 0xED // IPTC marker

View File

@ -1,630 +0,0 @@
//--------------------------------------------------------------------------
// Program to pull the information out of various types of EXIF digital
// camera files and show it in a reasonably consistent way
//
// This module handles basic Jpeg file handling
//
// Matthias Wandel
//--------------------------------------------------------------------------
#include "jhead.h"
// Storage for simplified info extracted from file.
ImageInfo_t ImageInfo;
static Section_t * Sections = NULL;
static int SectionsAllocated;
static int SectionsRead;
static int HaveAll;
#define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
//--------------------------------------------------------------------------
// Get 16 bits motorola order (always) for jpeg header stuff.
//--------------------------------------------------------------------------
static int Get16m(const void * Short)
{
return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
}
//--------------------------------------------------------------------------
// Process a COM marker.
// We want to print out the marker contents as legible text;
// we must guard against random junk and varying newline representations.
//--------------------------------------------------------------------------
static void process_COM (const uchar * Data, int length)
{
int ch;
char Comment[MAX_COMMENT_SIZE+1];
int nch;
int a;
nch = 0;
if (length > MAX_COMMENT_SIZE) length = MAX_COMMENT_SIZE; // Truncate if it won't fit in our structure.
for (a=2;a<length;a++){
ch = Data[a];
if (ch == '\r' && Data[a+1] == '\n') continue; // Remove cr followed by lf.
if (ch >= 32 || ch == '\n' || ch == '\t'){
Comment[nch++] = (char)ch;
}else{
Comment[nch++] = '?';
}
}
Comment[nch] = '\0'; // Null terminate
if (ShowTags){
printf("COM marker comment: %s\n",Comment);
}
strcpy(ImageInfo.Comments,Comment);
ImageInfo.CommentWidthchars = 0;
}
//--------------------------------------------------------------------------
// Process a SOFn marker. This is useful for the image dimensions
//--------------------------------------------------------------------------
static void process_SOFn (const uchar * Data, int marker)
{
int data_precision, num_components;
data_precision = Data[2];
ImageInfo.Height = Get16m(Data+3);
ImageInfo.Width = Get16m(Data+5);
num_components = Data[7];
if (num_components == 3){
ImageInfo.IsColor = 1;
}else{
ImageInfo.IsColor = 0;
}
ImageInfo.Process = marker;
if (ShowTags){
printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
ImageInfo.Width, ImageInfo.Height, num_components, data_precision);
}
}
//--------------------------------------------------------------------------
// Check sections array to see if it needs to be increased in size.
//--------------------------------------------------------------------------
void CheckSectionsAllocated(void)
{
if (SectionsRead > SectionsAllocated){
ErrFatal("allocation screwup");
}
if (SectionsRead >= SectionsAllocated){
SectionsAllocated += SectionsAllocated/2;
Sections = (Section_t *)realloc(Sections, sizeof(Section_t)*SectionsAllocated);
if (Sections == NULL){
ErrFatal("could not allocate data for entire image");
}
}
}
//--------------------------------------------------------------------------
// Parse the marker stream until SOS or EOI is seen;
//--------------------------------------------------------------------------
int ReadJpegSections (FILE * infile, ReadMode_t ReadMode)
{
int a;
int HaveCom = FALSE;
a = fgetc(infile);
if (a != 0xff || fgetc(infile) != M_SOI){
return FALSE;
}
ImageInfo.JfifHeader.XDensity = ImageInfo.JfifHeader.YDensity = 300;
ImageInfo.JfifHeader.ResolutionUnits = 1;
for(;;){
int itemlen;
int prev;
int marker = 0;
int ll,lh, got;
uchar * Data;
CheckSectionsAllocated();
prev = 0;
for (a=0;;a++){
marker = fgetc(infile);
if (marker != 0xff && prev == 0xff) break;
prev = marker;
}
if (a > 10){
ErrNonfatal("Extraneous %d padding bytes before section %02X",a-1,marker);
}
Sections[SectionsRead].Type = marker;
// Read the length of the section.
lh = fgetc(infile);
ll = fgetc(infile);
itemlen = (lh << 8) | ll;
if (itemlen < 2){
ErrFatal("invalid marker");
}
Sections[SectionsRead].Size = itemlen;
Data = (uchar *)malloc(itemlen);
if (Data == NULL){
ErrFatal("Could not allocate memory");
}
Sections[SectionsRead].Data = Data;
// Store first two pre-read bytes.
Data[0] = (uchar)lh;
Data[1] = (uchar)ll;
got = fread(Data+2, 1, itemlen-2, infile); // Read the whole section.
if (got != itemlen-2){
ErrFatal("Premature end of file?");
}
SectionsRead += 1;
switch(marker){
case M_SOS: // stop before hitting compressed data
// If reading entire image is requested, read the rest of the data.
if (ReadMode & READ_IMAGE){
int cp, ep, size;
// Determine how much file is left.
cp = ftell(infile);
fseek(infile, 0, SEEK_END);
ep = ftell(infile);
fseek(infile, cp, SEEK_SET);
size = ep-cp;
Data = (uchar *)malloc(size);
if (Data == NULL){
ErrFatal("could not allocate data for entire image");
}
got = fread(Data, 1, size, infile);
if (got != size){
ErrFatal("could not read the rest of the image");
}
CheckSectionsAllocated();
Sections[SectionsRead].Data = Data;
Sections[SectionsRead].Size = size;
Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
SectionsRead ++;
HaveAll = 1;
}
return TRUE;
case M_EOI: // in case it's a tables-only JPEG stream
fprintf(stderr,"No image in jpeg!\n");
return FALSE;
case M_COM: // Comment section
if (HaveCom || ((ReadMode & READ_METADATA) == 0)){
// Discard this section.
free(Sections[--SectionsRead].Data);
}else{
process_COM(Data, itemlen);
HaveCom = TRUE;
}
break;
case M_JFIF:
// Regular jpegs always have this tag, exif images have the exif
// marker instead, althogh ACDsee will write images with both markers.
// this program will re-create this marker on absence of exif marker.
// hence no need to keep the copy from the file.
if (memcmp(Data+2, "JFIF\0",5)){
fprintf(stderr,"Header missing JFIF marker\n");
}
if (itemlen < 16){
fprintf(stderr,"Jfif header too short\n");
goto ignore;
}
ImageInfo.JfifHeader.Present = TRUE;
ImageInfo.JfifHeader.ResolutionUnits = Data[9];
ImageInfo.JfifHeader.XDensity = (Data[10]<<8) | Data[11];
ImageInfo.JfifHeader.YDensity = (Data[12]<<8) | Data[13];
if (ShowTags){
printf("JFIF SOI marker: Units: %d ",ImageInfo.JfifHeader.ResolutionUnits);
switch(ImageInfo.JfifHeader.ResolutionUnits){
case 0: printf("(aspect ratio)"); break;
case 1: printf("(dots per inch)"); break;
case 2: printf("(dots per cm)"); break;
default: printf("(unknown)"); break;
}
printf(" X-density=%d Y-density=%d\n",ImageInfo.JfifHeader.XDensity, ImageInfo.JfifHeader.YDensity);
if (Data[14] || Data[15]){
fprintf(stderr,"Ignoring jfif header thumbnail\n");
}
}
ignore:
free(Sections[--SectionsRead].Data);
break;
case M_EXIF:
// There can be different section using the same marker.
if (ReadMode & READ_METADATA){
if (memcmp(Data+2, "Exif", 4) == 0){
process_EXIF(Data, itemlen);
break;
}else if (memcmp(Data+2, "http:", 5) == 0){
Sections[SectionsRead-1].Type = M_XMP; // Change tag for internal purposes.
if (ShowTags){
printf("Image cotains XMP section, %d bytes long\n", itemlen);
if (ShowTags){
ShowXmp(Sections[SectionsRead-1]);
}
}
break;
}
}
// Oterwise, discard this section.
free(Sections[--SectionsRead].Data);
break;
case M_IPTC:
if (ReadMode & READ_METADATA){
if (ShowTags){
printf("Image cotains IPTC section, %d bytes long\n", itemlen);
}
// Note: We just store the IPTC section. Its relatively straightforward
// and we don't act on any part of it, so just display it at parse time.
}else{
free(Sections[--SectionsRead].Data);
}
break;
case M_SOF0:
case M_SOF1:
case M_SOF2:
case M_SOF3:
case M_SOF5:
case M_SOF6:
case M_SOF7:
case M_SOF9:
case M_SOF10:
case M_SOF11:
case M_SOF13:
case M_SOF14:
case M_SOF15:
process_SOFn(Data, marker);
break;
default:
// Skip any other sections.
if (ShowTags){
printf("Jpeg section marker 0x%02x size %d\n",marker, itemlen);
}
break;
}
}
return TRUE;
}
//--------------------------------------------------------------------------
// Discard read data.
//--------------------------------------------------------------------------
void DiscardData(void)
{
int a;
for (a=0;a<SectionsRead;a++){
free(Sections[a].Data);
}
memset(&ImageInfo, 0, sizeof(ImageInfo));
SectionsRead = 0;
HaveAll = 0;
}
//--------------------------------------------------------------------------
// Read image data.
//--------------------------------------------------------------------------
int ReadJpegFile(const char * FileName, ReadMode_t ReadMode)
{
FILE * infile;
int ret;
infile = fopen(FileName, "rb"); // Unix ignores 'b', windows needs it.
if (infile == NULL) {
fprintf(stderr, "can't open '%s'\n", FileName);
return FALSE;
}
// Scan the JPEG headers.
ret = ReadJpegSections(infile, ReadMode);
if (!ret){
fprintf(stderr,"Not JPEG: %s\n",FileName);
}
fclose(infile);
if (ret == FALSE){
DiscardData();
}
return ret;
}
//--------------------------------------------------------------------------
// Discard everything but the exif and comment sections.
//--------------------------------------------------------------------------
void DiscardAllButExif(void)
{
Section_t ExifKeeper;
Section_t CommentKeeper;
Section_t IptcKeeper;
Section_t XmpKeeper;
int a;
memset(&ExifKeeper, 0, sizeof(ExifKeeper));
memset(&CommentKeeper, 0, sizeof(CommentKeeper));
memset(&IptcKeeper, 0, sizeof(IptcKeeper));
memset(&XmpKeeper, 0, sizeof(IptcKeeper));
for (a=0;a<SectionsRead;a++){
if (Sections[a].Type == M_EXIF && ExifKeeper.Type == 0){
ExifKeeper = Sections[a];
}else if (Sections[a].Type == M_XMP && XmpKeeper.Type == 0){
XmpKeeper = Sections[a];
}else if (Sections[a].Type == M_COM && CommentKeeper.Type == 0){
CommentKeeper = Sections[a];
}else if (Sections[a].Type == M_IPTC && IptcKeeper.Type == 0){
IptcKeeper = Sections[a];
}else{
free(Sections[a].Data);
}
}
SectionsRead = 0;
if (ExifKeeper.Type){
CheckSectionsAllocated();
Sections[SectionsRead++] = ExifKeeper;
}
if (CommentKeeper.Type){
CheckSectionsAllocated();
Sections[SectionsRead++] = CommentKeeper;
}
if (IptcKeeper.Type){
CheckSectionsAllocated();
Sections[SectionsRead++] = IptcKeeper;
}
if (XmpKeeper.Type){
CheckSectionsAllocated();
Sections[SectionsRead++] = XmpKeeper;
}
}
//--------------------------------------------------------------------------
// Write image data back to disk.
//--------------------------------------------------------------------------
void WriteJpegFile(const char * FileName)
{
FILE * outfile;
int a;
if (!HaveAll){
ErrFatal("Can't write back - didn't read all");
}
outfile = fopen(FileName,"wb");
if (outfile == NULL){
ErrFatal("Could not open file for write");
}
// Initial static jpeg marker.
fputc(0xff,outfile);
fputc(0xd8,outfile);
if (Sections[0].Type != M_EXIF && Sections[0].Type != M_JFIF){
// The image must start with an exif or jfif marker. If we threw those away, create one.
static uchar JfifHead[18] = {
0xff, M_JFIF,
0x00, 0x10, 'J' , 'F' , 'I' , 'F' , 0x00, 0x01,
0x01, 0x01, 0x01, 0x2C, 0x01, 0x2C, 0x00, 0x00
};
if (ImageInfo.ResolutionUnit == 2 || ImageInfo.ResolutionUnit == 3){
// Use the exif resolution info to fill out the jfif header.
// Usually, for exif images, there's no jfif header, so if wediscard
// the exif header, use info from the exif header for the jfif header.
ImageInfo.JfifHeader.ResolutionUnits = (char)(ImageInfo.ResolutionUnit-1);
// Jfif is 1 and 2, Exif is 2 and 3 for In and cm respecively
ImageInfo.JfifHeader.XDensity = (int)ImageInfo.xResolution;
ImageInfo.JfifHeader.YDensity = (int)ImageInfo.yResolution;
}
JfifHead[11] = ImageInfo.JfifHeader.ResolutionUnits;
JfifHead[12] = (uchar)(ImageInfo.JfifHeader.XDensity >> 8);
JfifHead[13] = (uchar)ImageInfo.JfifHeader.XDensity;
JfifHead[14] = (uchar)(ImageInfo.JfifHeader.YDensity >> 8);
JfifHead[15] = (uchar)ImageInfo.JfifHeader.YDensity;
fwrite(JfifHead, 18, 1, outfile);
// use the values from the exif data for the jfif header, if we have found values
if (ImageInfo.ResolutionUnit != 0) {
// JFIF.ResolutionUnit is {1,2}, EXIF.ResolutionUnit is {2,3}
JfifHead[11] = (uchar)ImageInfo.ResolutionUnit - 1;
}
if (ImageInfo.xResolution > 0.0 && ImageInfo.yResolution > 0.0) {
JfifHead[12] = (uchar)((int)ImageInfo.xResolution>>8);
JfifHead[13] = (uchar)((int)ImageInfo.xResolution);
JfifHead[14] = (uchar)((int)ImageInfo.yResolution>>8);
JfifHead[15] = (uchar)((int)ImageInfo.yResolution);
}
}
// Write all the misc sections
for (a=0;a<SectionsRead-1;a++){
fputc(0xff,outfile);
fputc((unsigned char)Sections[a].Type, outfile);
fwrite(Sections[a].Data, Sections[a].Size, 1, outfile);
}
// Write the remaining image data.
fwrite(Sections[a].Data, Sections[a].Size, 1, outfile);
fclose(outfile);
}
//--------------------------------------------------------------------------
// Check if image has exif header.
//--------------------------------------------------------------------------
Section_t * FindSection(int SectionType)
{
int a;
for (a=0;a<SectionsRead;a++){
if (Sections[a].Type == SectionType){
return &Sections[a];
}
}
// Could not be found.
return NULL;
}
//--------------------------------------------------------------------------
// Remove a certain type of section.
//--------------------------------------------------------------------------
int RemoveSectionType(int SectionType)
{
int a;
for (a=0;a<SectionsRead-1;a++){
if (Sections[a].Type == SectionType){
// Free up this section
free (Sections[a].Data);
// Move succeding sections back by one to close space in array.
memmove(Sections+a, Sections+a+1, sizeof(Section_t) * (SectionsRead-a));
SectionsRead -= 1;
return TRUE;
}
}
return FALSE;
}
//--------------------------------------------------------------------------
// Remove sectons not part of image and not exif or comment sections.
//--------------------------------------------------------------------------
int RemoveUnknownSections(void)
{
int a;
int Modified = FALSE;
for (a=0;a<SectionsRead-1;){
switch(Sections[a].Type){
case M_SOF0:
case M_SOF1:
case M_SOF2:
case M_SOF3:
case M_SOF5:
case M_SOF6:
case M_SOF7:
case M_SOF9:
case M_SOF10:
case M_SOF11:
case M_SOF13:
case M_SOF14:
case M_SOF15:
case M_SOI:
case M_EOI:
case M_SOS:
case M_JFIF:
case M_EXIF:
case M_XMP:
case M_COM:
case M_DQT:
case M_DHT:
case M_DRI:
case M_IPTC:
// keep.
a++;
break;
default:
// Unknown. Delete.
free (Sections[a].Data);
// Move succeding sections back by one to close space in array.
memmove(Sections+a, Sections+a+1, sizeof(Section_t) * (SectionsRead-a));
SectionsRead -= 1;
Modified = TRUE;
}
}
return Modified;
}
//--------------------------------------------------------------------------
// Add a section (assume it doesn't already exist) - used for
// adding comment sections and exif sections
//--------------------------------------------------------------------------
Section_t * CreateSection(int SectionType, unsigned char * Data, int Size)
{
Section_t * NewSection;
int a;
int NewIndex;
NewIndex = 2;
if (SectionType == M_EXIF) NewIndex = 0; // Exif alwas goes first!
// Insert it in third position - seems like a safe place to put
// things like comments.
if (SectionsRead < NewIndex){
ErrFatal("Too few sections!");
}
CheckSectionsAllocated();
for (a=SectionsRead;a>NewIndex;a--){
Sections[a] = Sections[a-1];
}
SectionsRead += 1;
NewSection = Sections+NewIndex;
NewSection->Type = SectionType;
NewSection->Size = Size;
NewSection->Data = Data;
return NewSection;
}
//--------------------------------------------------------------------------
// Initialisation.
//--------------------------------------------------------------------------
void ResetJpgfile(void)
{
if (Sections == NULL){
Sections = (Section_t *)malloc(sizeof(Section_t)*5);
SectionsAllocated = 5;
}
SectionsRead = 0;
HaveAll = 0;
}

View File

@ -1,191 +0,0 @@
//--------------------------------------------------------------------------
// Parse some maker specific onformation.
// (Very limited right now - add maker specific stuff to this module)
//--------------------------------------------------------------------------
#include "jhead.h"
extern int MotorolaOrder;
//--------------------------------------------------------------------------
// Process exif format directory, as used by Cannon maker note
//--------------------------------------------------------------------------
void ProcessCanonMakerNoteDir(unsigned char * DirStart, unsigned char * OffsetBase,
unsigned ExifLength)
{
int de;
int a;
int NumDirEntries;
NumDirEntries = Get16u(DirStart);
#define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
{
unsigned char * DirEnd;
DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries);
if (DirEnd > (OffsetBase+ExifLength)){
ErrNonfatal("Illegally sized Exif makernote subdir (%d entries)",NumDirEntries,0);
return;
}
if (DumpExifMap){
printf("Map: %05d-%05d: Directory (makernote)\n",(int)(DirStart-OffsetBase), (int)(DirEnd-OffsetBase));
}
}
if (ShowTags){
printf("(dir has %d entries)\n",NumDirEntries);
}
for (de=0;de<NumDirEntries;de++){
int Tag, Format, Components;
unsigned char * ValuePtr;
int ByteCount;
unsigned char * DirEntry;
DirEntry = DIR_ENTRY_ADDR(DirStart, de);
Tag = Get16u(DirEntry);
Format = Get16u(DirEntry+2);
Components = Get32u(DirEntry+4);
if ((Format-1) >= NUM_FORMATS) {
// (-1) catches illegal zero case as unsigned underflows to positive large.
ErrNonfatal("Illegal Exif number format %d for maker tag %04x", Format, Tag);
continue;
}
if ((unsigned)Components > 0x10000){
ErrNonfatal("Too many components (%d) for Exif maker tag %04x", Components, Tag);
continue;
}
ByteCount = Components * BytesPerFormat[Format];
if (ByteCount > 4){
unsigned OffsetVal;
OffsetVal = Get32u(DirEntry+8);
// If its bigger than 4 bytes, the dir entry contains an offset.
if (OffsetVal+ByteCount > ExifLength){
// Bogus pointer offset and / or bytecount value
ErrNonfatal("Illegal value pointer for Exif maker tag %04x", Tag,0);
continue;
}
ValuePtr = OffsetBase+OffsetVal;
if (DumpExifMap){
printf("Map: %05d-%05d: Data for makernote tag %04x\n",OffsetVal, OffsetVal+ByteCount, Tag);
}
}else{
// 4 bytes or less and value is in the dir entry itself
ValuePtr = DirEntry+8;
}
if (ShowTags){
// Show tag name
printf(" Canon maker tag %04x Value = ", Tag);
}
// Show tag value.
switch(Format){
case FMT_UNDEFINED:
// Undefined is typically an ascii string.
case FMT_STRING:
// String arrays printed without function call (different from int arrays)
if (ShowTags){
printf("\"");
for (a=0;a<ByteCount;a++){
int ZeroSkipped = 0;
if (ValuePtr[a] >= 32){
if (ZeroSkipped){
printf("?");
ZeroSkipped = 0;
}
putchar(ValuePtr[a]);
}else{
if (ValuePtr[a] == 0){
ZeroSkipped = 1;
}
}
}
printf("\"\n");
}
break;
default:
if (ShowTags){
PrintFormatNumber(ValuePtr, Format, ByteCount);
printf("\n");
}
}
if (Tag == 1 && Components > 16){
int IsoCode = Get16u(ValuePtr + 16*sizeof(unsigned short));
if (IsoCode >= 16 && IsoCode <= 24){
ImageInfo.ISOequivalent = 50 << (IsoCode-16);
}
}
if (Tag == 4 && Format == FMT_USHORT){
if (Components > 7){
int WhiteBalance = Get16u(ValuePtr + 7*sizeof(unsigned short));
switch(WhiteBalance){
// 0=Auto, 6=Custom
case 1: ImageInfo.LightSource = 1; break; // Sunny
case 2: ImageInfo.LightSource = 1; break; // Cloudy
case 3: ImageInfo.LightSource = 3; break; // Thungsten
case 4: ImageInfo.LightSource = 2; break; // Fourescent
case 5: ImageInfo.LightSource = 4; break; // Flash
}
}
if (Components > 19 && ImageInfo.Distance <= 0) {
// Indicates the distance the autofocus camera is focused to.
// Tends to be less accurate as distance increases.
int temp_dist = Get16u(ValuePtr + 19*sizeof(unsigned short));
if (temp_dist != 65535){
ImageInfo.Distance = (float)temp_dist/100;
}else{
ImageInfo.Distance = -1 /* infinity */;
}
}
}
}
}
//--------------------------------------------------------------------------
// Show generic maker note - just hex bytes.
//--------------------------------------------------------------------------
void ShowMakerNoteGeneric(unsigned char * ValuePtr, int ByteCount)
{
int a;
for (a=0;a<ByteCount;a++){
if (a > 10){
printf("...");
break;
}
printf(" %02x",ValuePtr[a]);
}
printf(" (%d bytes)", ByteCount);
printf("\n");
}
//--------------------------------------------------------------------------
// Process maker note - to the limited extent that its supported.
//--------------------------------------------------------------------------
void ProcessMakerNote(unsigned char * ValuePtr, int ByteCount,
unsigned char * OffsetBase, unsigned ExifLength)
{
if (strstr(ImageInfo.CameraMake, "Canon")){
// So it turns out that some canons cameras use big endian, others use little
// endian in the main exif header. But the maker note is always little endian.
static int MotorolaOrderSave;
MotorolaOrderSave = MotorolaOrder;
MotorolaOrder = 0; // Temporarily switch to little endian.
ProcessCanonMakerNoteDir(ValuePtr, OffsetBase, ExifLength);
MotorolaOrder = MotorolaOrderSave;
}else{
if (ShowTags){
ShowMakerNoteGeneric(ValuePtr, ByteCount);
}
}
}

View File

@ -0,0 +1,73 @@
/****************************************************************************
** Meta object code from reading C++ file 'filter_photosynth.h'
**
** Created: Thu Nov 25 13:56:00 2010
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "filter_photosynth.h"
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'filter_photosynth.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 62
#error "This file was generated using the moc from 4.7.0. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_FilterPhotosynthPlugin[] = {
// content:
5, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
static const char qt_meta_stringdata_FilterPhotosynthPlugin[] = {
"FilterPhotosynthPlugin\0"
};
const QMetaObject FilterPhotosynthPlugin::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_FilterPhotosynthPlugin,
qt_meta_data_FilterPhotosynthPlugin, 0 }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &FilterPhotosynthPlugin::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *FilterPhotosynthPlugin::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *FilterPhotosynthPlugin::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_FilterPhotosynthPlugin))
return static_cast<void*>(const_cast< FilterPhotosynthPlugin*>(this));
if (!strcmp(_clname, "MeshFilterInterface"))
return static_cast< MeshFilterInterface*>(const_cast< FilterPhotosynthPlugin*>(this));
if (!strcmp(_clname, "vcg.meshlab.MeshFilterInterface/1.0"))
return static_cast< MeshFilterInterface*>(const_cast< FilterPhotosynthPlugin*>(this));
return QObject::qt_metacast(_clname);
}
int FilterPhotosynthPlugin::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
return _id;
}
QT_END_MOC_NAMESPACE

View File

@ -0,0 +1,100 @@
/****************************************************************************
** Meta object code from reading C++ file 'qtsoap.h'
**
** Created: Thu Nov 25 13:31:30 2010
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "../../external/qtsoap-2.7_1/src/qtsoap.h"
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qtsoap.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 62
#error "This file was generated using the moc from 4.7.0. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_QtSoapHttpTransport[] = {
// content:
5, // revision
0, // classname
0, 0, // classinfo
3, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: signature, parameters, type, tag, flags
21, 20, 20, 20, 0x05,
46, 37, 20, 20, 0x05,
// slots: signature, parameters, type, tag, flags
81, 75, 20, 20, 0x08,
0 // eod
};
static const char qt_meta_stringdata_QtSoapHttpTransport[] = {
"QtSoapHttpTransport\0\0responseReady()\0"
"response\0responseReady(QtSoapMessage)\0"
"reply\0readResponse(QNetworkReply*)\0"
};
const QMetaObject QtSoapHttpTransport::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_QtSoapHttpTransport,
qt_meta_data_QtSoapHttpTransport, 0 }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &QtSoapHttpTransport::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *QtSoapHttpTransport::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *QtSoapHttpTransport::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_QtSoapHttpTransport))
return static_cast<void*>(const_cast< QtSoapHttpTransport*>(this));
return QObject::qt_metacast(_clname);
}
int QtSoapHttpTransport::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: responseReady(); break;
case 1: responseReady((*reinterpret_cast< const QtSoapMessage(*)>(_a[1]))); break;
case 2: readResponse((*reinterpret_cast< QNetworkReply*(*)>(_a[1]))); break;
default: ;
}
_id -= 3;
}
return _id;
}
// SIGNAL 0
void QtSoapHttpTransport::responseReady()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
// SIGNAL 1
void QtSoapHttpTransport::responseReady(const QtSoapMessage & _t1)
{
void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
QT_END_MOC_NAMESPACE

View File

@ -1,38 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// Defines utility functions for Qt's QByteArray class.
#ifndef QITTY_UTILS_BYTE_ARRAY_H_
#define QITTY_UTILS_BYTE_ARRAY_H_
class QByteArray;
namespace qitty_utils {
bool EqualToInt(QByteArray byte_array, int value);
QByteArray ReverseByteArray(QByteArray byte_array);
int ToInt(QByteArray byte_array);
} // namespace qitty_utils
#endif // QITTY_UTILS_BYTE_ARRAY_H_

View File

@ -1,37 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// Utility functions for image-related processing.
#ifndef QITTY_UTILS_IMAGE_H_
#define QITTY_UTILS_IMAGE_H_
class QImage;
class QString;
namespace qitty_utils {
QImage SacledImage(const QString &file_name, int length);
} // namespace qitty_utils
#endif // QITTY_UTILS_IMAGE_H_

View File

@ -1,78 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// This file defines the LineEdit class which enhances the QLineEdit class.
#ifndef QITTY_WIDGETS_LINE_EDIT_H_
#define QITTY_WIDGETS_LINE_EDIT_H_
#include <QLineEdit>
namespace qitty_widgets {
class LineEdit : public QLineEdit {
Q_OBJECT
public:
LineEdit(QWidget *parent = NULL);
LineEdit(const QString &contents, QWidget *parent = NULL);
void SetHint(const QString &hint);
// Accessor functions for properties.
void set_clear_focus_when_return_pressed(bool b) {
clear_focus_when_return_pressed_ = b;
}
bool is_modified() { return is_modified_; }
signals:
// This signal is emitted whenever the focus is out.
void FocusOut();
protected:
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
private slots:
void ClearFocusWhenReturnPressed();
void SetModifiedToTrue();
private:
void Init();
// Accessor functions for properties.
bool clear_focus_when_return_pressed() {
return clear_focus_when_return_pressed_;
}
QString hint() { return hint_; }
void set_hint(QString hint) { hint_ = hint; }
void set_is_modified(bool is_modified) { is_modified_ = is_modified; }
// Whether to clear focus when the Return or Enter key is pressed.
bool clear_focus_when_return_pressed_;
// Whether the text is modified or not, this value is updated by the
// textEdited() signal and the SetModifiedToTrue() slot.
bool is_modified_;
// The hint displayed as text if focus is out.
QString hint_;
};
} // namespace qitty_widgets
#endif // QITTY_WIDGETS_LINE_EDIT_H_

View File

@ -1,118 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// This file defines the PlainTextEdit widget, which enhances the QPlainTextEdit
// class.
#ifndef QITTY_WIDGETS_PLAIN_TEXT_EDIT_H_
#define QITTY_WIDGETS_PLAIN_TEXT_EDIT_H_
#include <QPlainTextEdit>
#include <QSize>
class QResizeEvent;
namespace qitty_widgets {
class PlainTextEdit : public QPlainTextEdit {
Q_OBJECT
public:
enum Mode {
kNormalMode = 0,
// The height will be changed to adapt the text.
kElasticMode,
};
PlainTextEdit(Mode mode = kNormalMode, QWidget *parent = NULL);
// Accessor functions for properties.
void set_clear_focus_when_return_pressed(bool b) {
clear_focus_when_return_pressed_ = b;
}
void set_mode(Mode mode) {
mode_ = mode;
emit ModeChanged(mode);
}
bool is_modified() { return is_modified_; }
void set_minimum_line_number(int number) { minimum_line_number_ = number; }
signals:
// This signal is emitted whenever the focus is out.
void FocusOut();
// This signal is emitted whenever the mode is changed.
void ModeChanged(Mode mode);
protected:
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
void keyPressEvent(QKeyEvent *event);
void mousePressEvent(QMouseEvent *event);
void resizeEvent(QResizeEvent *event);
// Overwrites the wheelEvent() to deactivate the wheel.
// void wheelEvent(QWheelEvent *event) {}
private slots:
void RecoverCursorWidth();
void UpdateAllSelected();
void UpdateHeight();
void UpdateModeState(Mode mode);
void UpdateModified(bool changed);
private:
void Init(Mode mode);
void UpdateMinimumHeight();
// Accessor functions for properties.
bool all_selected() { return all_selected_; }
void set_all_selected(bool b) { all_selected_ = b; }
bool clear_focus_when_return_pressed() {
return clear_focus_when_return_pressed_;
}
int initial_cursor_width() { return initial_cursor_width_; }
void set_initial_cursor_width(int width) { initial_cursor_width_ = width; }
void set_is_modified(bool b) { is_modified_ = b; }
int minimum_height() { return minimum_height_; }
void set_minimum_height(int height) { minimum_height_ = height; }
int minimum_line_number() { return minimum_line_number_; }
Mode mode() { return mode_; }
// Sets to true if full text is selected.
bool all_selected_;
// Whether to clear focus when the Return or Enter key is pressed.
bool clear_focus_when_return_pressed_;
// The initial width of the cursor of this widget.
int initial_cursor_width_;
// Whether the text is modified or not, this value is updated by the
// modificationChanged() signal and the UpdateModified() slot.
bool is_modified_;
// The minimum height of this widget. The value will be calculated in the
// UpdateMinimumHeight() function.
int minimum_height_;
// The minimum line number of this widget. This value is used to determine
// the minimum height of this widget in the kElasticMode.
int minimum_line_number_;
// Current mode of the widget.
Mode mode_;
};
} // namespace qitty_widgets
#endif // QITTY_WIDGETS_PLAIN_TEXT_EDIT_H_

View File

@ -1,5 +0,0 @@
#include "qitty/byte_array.h"
#include "qitty/image.h"
#include "qitty/line_edit.h"
#include "qitty/plain_text_edit.h"
#include "qitty/style_sheet.h"

View File

@ -1,35 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
#ifndef QITTY_UTILS_STYLE_SHEET_H_
#define QITTY_UTILS_STYLE_SHEET_H_
class QString;
class QWidget;
namespace qitty_utils {
void SetStyleSheet(QWidget *widget, const QString &path);
} // namespace qitty_utils
#endif // QITTY_UTILS_STYLE_SHEET_H_

View File

@ -1,213 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Exif class.
#ifndef QMETA_EXIF_H_
#define QMETA_EXIF_H_
#include <QHash>
#include "qmeta/exif_data.h"
#include "qmeta/identifiers.h"
#include "qmeta/standard.h"
class QIODevice;
namespace qmeta {
class TiffHeader;
class Exif : public Standard {
Q_OBJECT
public:
enum Tag {
// Exif-specific IFD.
kExifIfdPointer = 34665,
kGpsInfoIfdPointer = 34853,
kInteroperabilityIfdPointer = 40965,
// TIFF Rev. 6.0 attribute information used in Exif, represented in decimal.
// Tags relating to image data structure.
kImageWidth = 256, // Image width
kImageLength = 257, // Image height
kBitsPerSample = 258, // Number of bits per component
kCompression = 259, // Compression scheme
kPhotometricInterpretation = 262, // Pixel composition
kOrientation = 274, // Orientation of image
kSamplesPerPixel = 277, // Number of components
kPlanarConfiguration = 284, // Image data arrangement
kYCbCrSubSampling = 530, // Subsampling ratio of Y to C
kYCbCrPositioning = 531, // Y and C positioning
kXResolution = 282, // Image resolution in width direction
kYResolution = 283, // Image resolution in height direction
kResolutionUnit = 296, // Unit of X and Y resolution
// Tags relating to recording offset.
kStripOffsets = 273, // Image data location
kRowsPerStrip = 278, // Number of rows per strip
kStripByteCounts = 279, // Bytes per compressed strip
kJPEGInterchangeFormat = 513, // Offset to JPEG SOI
kJPEGInterchangeFormatLength = 514, // Bytes of JPEG data
// Tags relating to image data characteristics.
kTransferFunction = 301, // Transfer function
kWhitePoint = 318, // White point chromaticity
kPrimaryChromaticities = 319, // Chromaticities of primaries
kYCbCrCoefficients = 529, // Color space transformation matrix coefficients
kReferenceBlackWhite = 532, // Pair of black and white reference values
// Other tags.
kDateTime = 306, // File change date and time
kImageDescription = 270, // Image title
kMake = 271, // Image input equipment manufacturer
kModel = 272, // Image input equipment model
kSoftware = 305, // Software used
kArtist = 315, // Person who created the image
kCopyright = 33432, // Copyright holder
// The attribute information recorded in the Exif IFD.
// Tags relating to version.
kExifVersion = 36864, // Exif version
kFlashpixVersion = 40960, // Supported Flashpix version
// Tag relating to image data characteristics.
kColorSpace = 40961, // Color space information
// Tags relating to image configuration.
kComponentsConfiguration = 37121, // Meaning of each component
kCompressedBitsPerPixel = 37122, // Image compression mode
kPixelXDimension = 40962, // Valid image width
kPixelYDimension = 40963, // Valid image height
// Tags relating to user information.
kMakerNote = 37500, // Manufacturer notes
kUserComment = 37510, // User comments
// Tags relating to related file information.
kRelatedSoundFile = 40964,
// Tags relating to date and time.
kDateTimeOriginal = 36867, // Date and time of original data generation
kDateTimeDigitized = 36868, // Date and time of digital data generation
kSubSecTime = 37520, // Date Time subseconds
kSubSecTimeOriginal = 37521, // Date Time Original subseconds
kSubSecTimeDigitized = 37522, // Date Time Digitized subseconds
// Tags relating to picture-taking conditions.
kExposureTime = 33434, // Exposure time
kFNumber = 33437, // F number
kExposureProgram = 34850, // Exposure program
kSpectralSensitivity = 34852, // Spectral sensitivity
kISOSpeedRatings = 34855, // ISO speed rating
kOECF = 34856, // Optoelectric conversion factor
kShutterSpeedValue = 37377, // Shutter speed
kApertureValue = 37378, // Aperture
kBrightnessValue = 37379, // Brightness
kExposureBiasValue = 37380, // Exposure bias
kMaxApertureValue = 37381, // Maximum lens aperture
kSubjectDistance = 37382, // Subject distance
kMeteringMode = 37383, // Metering mode
kLightSource = 37384, // Light source
kFlash = 37385, // Flash
kFocalLength = 37386, //Lens focal length
kSubjectArea = 37396, // Subject area
kFlashEnergy = 41483, // Flash energy
kSpatialFrequencyResponse = 41484, // Spatial frequency response
kFocalPlaneXResolution = 41486, // Focal plane X resolution
kFocalPlaneYResolution = 41487, // Focal plane Y resolution
kFocalPlaneResolutionUnit = 41488, // Focal plane resolution unit
kSubjectLocation = 41492, // Subject location
kExposureIndex = 41493, // Exposure index
kSensingMethod = 41495, // Sensing method
kFileSource = 41728, // File source
kSceneType = 41729, // Scene type
kCFAPattern = 41730, // CFA pattern
kCustomRendered = 41985, // Custom image processing
kExposureMode = 41986, // Exposure mode
kWhiteBalance = 41987, // White balance
kDigitalZoomRatio = 41988, //Digital zoom ratio
kFocalLengthIn35mmFilm = 41989, // Focal length in 35 mm film
kSceneCaptureType = 41990, // Scene capture type
kGainControl = 41991, // Gain control
kContrast = 41992, // Contrast
kSaturation = 41993, // Saturation
kSharpness = 41994, // Sharpness
kDeviceSettingDescription = 41995, // Device settings description
kSubjectDistanceRange = 41996, // Subject distance range
// Other tags.
kImageUniqueID = 42016, // Unique image ID
// The attribute information recorded in the GPS Info IFD.
kGPSVersionID = 0, // GPS tag version
kGPSLatitudeRef = 1, // North or South Latitude
kGPSLatitude = 2, // Latitude
kGPSLongitudeRef = 3, // East or West Longitude
kGPSLongitude = 4, // Longitude
kGPSAltitudeRef = 5, // Altitude reference
kGPSAltitude = 6, // Altitude
kGPSTimeStamp = 7, // GPS time (atomic clock)
kGPSSatellites = 8, // GPS satellites used for measurement
kGPSStatus = 9, // GPS receiver status
kGPSMeasureMode = 10, // GPS measurement mode
kGPSDOP = 11, // Measurement precision
kGPSSpeedRef = 12, // Speed unit
kGPSSpeed = 13, // Speed of GPS receiver
kGPSTrackRef = 14, // Reference for direction of movement
kGPSTrack = 15, // Direction of movement
kGPSImgDirectionRef = 16, // Reference for direction of image
kGPSImgDirection = 17, // Direction of image
kGPSMapDatum = 18, // Geodetic survey data used
kGPSDestLatitudeRef = 19, // Reference for latitude of destination
kGPSDestLatitude = 20, // Latitude of destination
kGPSDestLongitudeRef = 21, // Reference for longitude of destination
kGPSDestLongitude = 22, // Longitude of destination
kGPSDestBearingRef = 23, // Reference for longitude of destination
kGPSDestBearing = 24, // Bearing of destination
kGPSDestDistanceRef = 25, // Reference for distance to destination
kGPSDestDistance = 26, // Distance to destination
kGPSProcessingMethod = 27, // Name of GPS processing method
kGPSAreaInformation = 28, // Name of GPS area
kGPSDateStamp = 29, // GPS date
kGPSDifferential = 30, // GPS differential correction
};
explicit Exif(QObject *parent = NULL);
bool Init(QIODevice *file, TiffHeader *tiff_header);
QByteArray Thumbnail();
ExifData Value(Tag tag);
QHash<Tag, QString> tag_names() const { return tag_names_; }
private:
void InitTagNames();
void ReadIfds(int ifd_offset);
void set_tag_names(QHash<Tag, QString> names) { tag_names_ = names; }
QHash<Tag, qint64> tag_offsets() const { return tag_offsets_; }
void set_tag_offsets(QHash<Tag, qint64> offsets) { tag_offsets_ = offsets; }
TiffHeader* tiff_header() const { return tiff_header_; }
void set_tiff_header(TiffHeader *tiff_header) { tiff_header_ = tiff_header; }
// The tag names to read for human.
QHash<Tag, QString> tag_names_;
// Records offsets of tags used in Exif.
QHash<Tag, qint64> tag_offsets_;
// Tracks the TiffHeader object.
TiffHeader *tiff_header_;
};
} // namespace qmeta
#endif // QMETA_EXIF_H_

View File

@ -1,45 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines all classes for supported Types and specific tag data in
// Exif. All classes should inherit from the ExifData class.
#ifndef QMETA_EXIF_DATA_H_
#define QMETA_EXIF_DATA_H_
#include <QObject>
namespace qmeta {
class ExifData : public QByteArray {
public:
ExifData(const QByteArray &other);
double ToDouble();
float ToFloat();
int ToInt();
QString ToString();
uint ToUInt();
};
} // namespace qmeta
#endif // QMETA_EXIF_DATA_H_

View File

@ -1,84 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the File class which is the base class for all QMeta
// supported file types.
#ifndef QMETA_FILE_H_
#define QMETA_FILE_H_
#include <QObject>
class QIODevice;
namespace qmeta {
class Exif;
class Iptc;
class Xmp;
class File : public QObject {
public:
explicit File(QByteArray *data);
explicit File(QIODevice *file);
explicit File(const QString &file_name);
QByteArray Thumbnail();
Exif* exif() const { return exif_; }
Iptc* iptc() const { return iptc_; }
Xmp* xmp() const { return xmp_; }
protected:
// Initializes the Exif object.
virtual void InitExif() {};
virtual void InitIptc() {};
void InitMetadata();
virtual void InitXmp() {};
void set_exif(Exif *exif) { exif_ = exif; }
QIODevice* file() const { return file_; }
void set_iptc(Iptc *iptc) { iptc_ = iptc; }
void set_xmp(Xmp *xmp) { xmp_ = xmp; }
private:
// Returns true if the tracked file is valid. This function should be
// reimplemented in all subclasses to verify specific file types.
virtual bool IsValid() { return false; }
void set_file(QIODevice *file) { file_ = file; }
// The corresponded Exif object of the tracked file. This property is set
// if the tracked file supports the EXIF standard.
Exif *exif_;
// Tracks the current opened file.
QIODevice *file_;
// The corresponded Iptc object of the tracked file. This property is set
// if the tracked file supports the IPTC standard.
Iptc *iptc_;
// The corresponded Xmp object of the tracked file. This property is set
// if the tracked file supports the XMP standard.
Xmp *xmp_;
};
} // namespace qmeta
#endif // QMETA_FILE_H_

View File

@ -1,43 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines miscellaneous identifiers used throguh the QMeta library.
#ifndef QMETA_IDENTIFIERS_H_
#define QMETA_IDENTIFIERS_H_
namespace qmeta {
enum Endianness {
kLittleEndians = 0,
kBigEndians,
};
enum FileType {
kInvalidFileType = 0,
kJpegFileType,
kTiffFileType,
};
} // namespace qmeta
#endif // QMETA_IDENTIFIERS_H_

View File

@ -1,59 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Image class, which has the ability to guess the file
// type of the specified image data, and can be used as a normal file class
// such as Jpeg, Tiff, etc.
#ifndef QMETA_IMAGE_H_
#define QMETA_IMAGE_H_
#include "qmeta/exif.h"
#include "qmeta/file.h"
#include "qmeta/identifiers.h"
#include "qmeta/iptc.h"
#include "qmeta/jpeg.h"
#include "qmeta/tiff.h"
#include "qmeta/xmp.h"
namespace qmeta {
class Image : public File {
public:
explicit Image(QByteArray *data);
explicit Image(QIODevice *file);
explicit Image(const QString &file_name);
bool IsValid();
FileType file_type() const { return file_type_; }
private:
void GuessType();
template<class T> bool GuessType(FileType file_type);
void set_file_type(FileType file_type) { file_type_ = file_type; }
FileType file_type_;
};
} // namespace qmeta
#endif // QMETA_IMAGE_H_

View File

@ -1,130 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Iptc class.
#ifndef QMETA_IPTC_H_
#define QMETA_IPTC_H_
#include <QHash>
#include "standard.h"
class QIODevice;
namespace qmeta {
class Iptc : public Standard {
Q_OBJECT
public:
// Only contains the list of valid editorial IPTC tags (2:xx).
enum Tag {
kRecordVersion = 0,
kObjectTypeReference = 3,
kObjectAttributeReference = 4,
kObjectName = 5,
kEditStatus = 7,
kEditorialUpdate = 8,
kUrgency = 10,
kSubjectReference = 12,
kCategory = 15,
kSupplementalCategory = 20,
kFixtureIdentifier = 22,
kKeywords = 25,
kContentLocationCode = 26,
kContentLocationName = 27,
kReleaseDate = 30,
kReleaseTime = 35,
kExpirationDate = 37,
kExpirationTime = 38,
kSpecialInstructions = 40,
kActionAdvised = 42,
kReferenceService = 45,
kReferenceDate = 47,
kReferenceNumber = 50,
kDateCreated = 55,
kTimeCreated = 60,
kDigitalCreationDate = 62,
kDigitalCreationTime = 63,
kOriginatingProgram = 65,
kProgramVersion = 70,
kObjectCycle = 75,
kByLine = 80,
kByLineTitle = 85,
kCity = 90,
kSubLocation = 92,
kProvinceState = 95,
kCountryPrimaryLocationCode = 100,
kCountryPrimaryLocationName = 101,
kOriginalTransmissionReference = 103,
kHeadline = 105,
kCredit = 110,
kSource = 115,
kCopyrightNotice = 116,
kContact = 118,
kCaptionAbstract = 120,
kWriterEditor = 122,
kRasterizedCaption = 125,
kImageType = 130,
kImageOrientation = 131,
kLanguageIdentifier = 135,
kAudioType = 150,
kAudioSamplingRate = 151,
kAudioSamplingResolution = 152,
kAudioDuration = 153,
kAudioOutcue = 154,
kObjDataPreviewFileFormat = 200,
kObjDataPreviewFileFormatVer = 201,
kObjDataPreviewData = 202,
};
explicit Iptc(QObject *parent = NULL);
bool Init(QIODevice *file, const qint64 file_start_offset);
QByteArray Value(Tag tag);
QList<QByteArray> Values(Tag tag);
QHash<Tag, QString> tag_names() const { return tag_names_; }
private:
void InitRepeatableTags();
void InitTagNames();
QByteArray ReadDataSet(int offset);
bool ReadRecord();
QList<Tag> repeatable_tags() const { return repeatable_tags_; }
void set_repeatable_tags(QList<Tag> tags) { repeatable_tags_ = tags; }
void set_tag_names(QHash<Tag, QString> names) { tag_names_ = names; }
QHash<Tag, qint64> tag_offsets() const { return tag_offsets_; }
void set_tag_offsets(QHash<Tag, qint64> offsets) { tag_offsets_ = offsets; }
// Records the repeatable tags.
QList<Tag> repeatable_tags_;
// The tag names to read for human.
QHash<Tag, QString> tag_names_;
// Records offsets of tags used in IPTC.
QHash<Tag, qint64> tag_offsets_;
};
} // namespace qmeta
#endif // QMETA_IPTC_H_

View File

@ -1,49 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Jpeg class.
#ifndef QMETA_JPEG_
#define QMETA_JPEG_
#include "qmeta/file.h"
class QString;
namespace qmeta {
class Jpeg : public File {
public:
explicit Jpeg(QByteArray *data);
explicit Jpeg(QIODevice *file);
explicit Jpeg(const QString &file_name);
bool IsValid();
private:
void InitExif();
void InitIptc();
void InitXmp();
};
} // namespace qmeta
#endif // QMETA_JPEG_

View File

@ -1,12 +0,0 @@
#include "exif.h"
#include "exif_data.h"
#include "file.h"
#include "identifiers.h"
#include "image.h"
#include "iptc.h"
#include "jpeg.h"
#include "standard.h"
#include "tiff.h"
#include "tiff_header.h"
#include "xmp.h"
#include "qmeta.h"

View File

@ -1,55 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Standard class, which is the base class for all
// metadata standard classes such as Exif and Iptc.
#ifndef QMETA_STANDARD_H_
#define QMETA_STANDARD_H_
#include <QObject>
class QIODevice;
namespace qmeta {
class Standard : public QObject {
Q_OBJECT
public:
explicit Standard(QObject *parent = NULL);
protected:
QIODevice* file() const { return file_; }
void set_file(QIODevice *file) { file_ = file; }
qint64 file_start_offset() const { return file_start_offset_; }
void set_file_start_offset(qint64 offset) { file_start_offset_ = offset; }
// Tracks the file containing the metadata.
QIODevice *file_;
// The offset of the beginning of the metadata standard in the tracked file.
qint64 file_start_offset_;
};
} // namespace qmeta
#endif // QMETA_STANDARD_H_

View File

@ -1,58 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the TIFF class.
#ifndef QMETA_TIFF_H_
#define QMETA_TIFF_H_
#include "qmeta/file.h"
class QString;
namespace qmeta {
class TiffHeader;
class Tiff : public File {
public:
explicit Tiff(QByteArray *data);
explicit Tiff(QIODevice *file);
explicit Tiff(const QString &file_name);
void Init();
bool IsValid();
private:
void InitExif();
void InitIptc();
void InitXmp();
TiffHeader* tiff_header() const { return tiff_header_; }
void set_tiff_header(TiffHeader *tiff_header) { tiff_header_ = tiff_header; }
// Tracks the TiffHeader object of the tracked file.
TiffHeader *tiff_header_;
};
} // namespace qmeta
#endif // QMETA_TIFF_H_

View File

@ -1,128 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the TiffHeader class which is used for TIFF files and
// Exif metadata embeded in JPEG files. Both the Tiff and the Jpeg classes
// should instantiate the TiffHeader object and pass it to the corresponded
// Exif object.
#ifndef QMETA_TIFF_HEADER_H_
#define QMETA_TIFF_HEADER_H_
#include <QHash>
#include <QObject>
#include "qmeta/identifiers.h"
class QIODevice;
namespace qmeta {
class TiffHeader : public QObject {
Q_OBJECT
public:
// The value data types used in TIFF header.
enum Type {
// An 8-bit unsigned integer.
kByteType = 1,
// An 8-bit byte containing one 7-bit ASCII code. The final byte is
// terminated with NULL.
kAsciiType = 2,
// A 16-bit (2-byte) unsigned integer.
kShortType = 3,
// A 32-bit (4-byte) unsigned integer.
kLongType = 4,
// Two LONGs. The first LONG is the numerator and the second LONG expresses
// the denominator.
kRationalType = 5,
// An 8-bit signed integer.
kSByte = 6,
// An 8-bit byte that can take any value depending ont he field definition.
kUndefinedType = 7,
// A 16-bit signed integer.
kSShort = 8,
// A 32-bit (4-byte) signed integer (2's complement notation)
kSLongType = 9,
// Two SLONGs. The first SLONG is the numerator and the second SLONG is the
// denominator.
kSRationalType = 10,
// A 4-byte IEEE floating point value.
kFloat = 11,
// An 8-byte IEEE floating point value.
kDouble = 12,
};
explicit TiffHeader(QObject *parent = NULL);
bool HasNextIfdEntry();
int IfdEntryTag(qint64 ifd_entry_offset);
Type IfdEntryType(qint64 ifd_entry_offset);
QByteArray IfdEntryValue(qint64 ifd_entry_offset);
qint64 IfdEntryOffset(qint64 ifd_entry_offset);
bool Init(QIODevice *file, qint64 file_start_offset);
qint64 NextIfdEntryOffset();
void ToFirstIfd();
void ToIfd(qint64 offset);
qint64 current_ifd_offset() const { return current_ifd_offset_; }
qint64 file_start_offset() const { return file_start_offset_; }
private:
void InitTypeByteUnit();
QByteArray ReadFromFile(const int max_size);
int current_entry_count() const { return current_entry_count_; }
void set_current_entry_count(int count) { current_entry_count_ = count; }
int current_entry_number() const { return current_entry_number_; }
void set_current_entry_number(int number) { current_entry_number_ = number; }
void set_current_ifd_offset(qint64 offset) { current_ifd_offset_ = offset; }
Endianness endianness() const { return endianness_; }
void set_endianness(Endianness endian) { endianness_ = endian; }
QIODevice* file() const { return file_; }
void set_file(QIODevice *file) { file_ = file; }
void set_file_start_offset(qint64 offset) { file_start_offset_ = offset; }
int first_ifd_offset() const { return first_ifd_offset_; }
void set_first_ifd_offset(int offset) { first_ifd_offset_ = offset; }
QHash<Type, int> type_byte_unit() const { return type_byte_unit_; }
void set_type_byte_unit(QHash<Type, int> unit) { type_byte_unit_ = unit; }
// The count of directory entries of the current IFD.
int current_entry_count_;
// The number of current directory entry in the IFD.
int current_entry_number_;
// Tracks the beginning offset of current IFD.
int current_ifd_offset_;
// The byte order of the TIFF file.
Endianness endianness_;
// The tracked file.
QIODevice *file_;
// The beginning offset of the TIFF header in the tracked file.
qint64 file_start_offset_;
// The offset of the first IFD.
int first_ifd_offset_;
// The byte unit for each entry type.
QHash<Type, int> type_byte_unit_;
};
} // namespace qmeta
#endif // QMETA_TIFF_HEADER_H_

View File

@ -1,46 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file defines the Xmp class.
#ifndef QMETA_XMP_H_
#define QMETA_XMP_H_
#include <QHash>
#include "qmeta/standard.h"
class QIODevice;
namespace qmeta {
class Xmp : public Standard {
Q_OBJECT
public:
explicit Xmp(QObject *parent = NULL);
bool Init(QIODevice *file, qint64 file_start_offset);
};
} // namespace qmeta
#endif // QMETA_XMP_H_

View File

@ -1,239 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the Exif class.
#include "qmeta/exif.h"
#include <QtCore>
#include <qitty/byte_array.h>
#include "qmeta/tiff_header.h"
namespace qmeta {
Exif::Exif(QObject *parent) : Standard(parent) {
InitTagNames();
QHash<Tag, qint64> tag_offsets;
set_tag_offsets(tag_offsets);
}
// Initializes the Exif object.
bool Exif::Init(QIODevice *file, TiffHeader *tiff_header) {
set_file(file);
set_tiff_header(tiff_header);
tiff_header->ToFirstIfd();
ReadIfds(tiff_header->current_ifd_offset());
if (tag_offsets().count() == 0)
return false;
else
return true;
}
// Initializes tag names used in Exif.
void Exif::InitTagNames() {
QHash<Tag, QString> tag_names;
// Exif-specific IFD.
tag_names.insert(kExifIfdPointer, tr("Exif IFD Pointer"));
tag_names.insert(kGpsInfoIfdPointer, tr("GPS Info IFD Pointer"));
tag_names.insert(kInteroperabilityIfdPointer,
tr("Interoperability IFD Pointer"));
// TIFF Rev. 6.0 attribute information used in Exif.
tag_names.insert(kImageWidth, tr("Image Width"));
tag_names.insert(kImageLength, tr("Image Height"));
tag_names.insert(kBitsPerSample, tr("Bits Per Sample"));
tag_names.insert(kCompression, tr("Compression"));
tag_names.insert(kPhotometricInterpretation,
tr("Photometric Interpretation"));
tag_names.insert(kOrientation, tr("Orientation"));
tag_names.insert(kSamplesPerPixel, tr("Samples Per Pixel"));
tag_names.insert(kPlanarConfiguration, tr("Planar Configuration"));
tag_names.insert(kYCbCrSubSampling, tr("YCbCr Sub Sampling"));
tag_names.insert(kYCbCrPositioning, tr("YCbCr Positioning"));
tag_names.insert(kXResolution, tr("X-Resolution"));
tag_names.insert(kYResolution, tr("Y-Resolution"));
tag_names.insert(kResolutionUnit, tr("Resolution Unit"));
tag_names.insert(kStripOffsets, tr("Strip Offsets"));
tag_names.insert(kRowsPerStrip, tr("Rows Per Strip"));
tag_names.insert(kStripByteCounts, tr("Strip Byte Counts"));
tag_names.insert(kJPEGInterchangeFormat, tr("JPEG Interchange Format"));
tag_names.insert(kJPEGInterchangeFormatLength,
tr("JPEG Interchange Format Length"));
tag_names.insert(kTransferFunction, tr("Transfer Function"));
tag_names.insert(kWhitePoint, tr("White Point"));
tag_names.insert(kPrimaryChromaticities, tr("Primary Chromaticities"));
tag_names.insert(kYCbCrCoefficients, tr("YCbCr Coefficients"));
tag_names.insert(kReferenceBlackWhite, tr("Reference Black White"));
tag_names.insert(kDateTime, tr("Date Time"));
tag_names.insert(kImageDescription, tr("Image Description"));
tag_names.insert(kMake, tr("Make"));
tag_names.insert(kModel, tr("Model"));
tag_names.insert(kSoftware, tr("Software"));
tag_names.insert(kArtist, tr("Artist"));
tag_names.insert(kCopyright, tr("Copyright"));
// The attribute information recorded in the Exif IFD.
tag_names.insert(kExifVersion, tr("Exif Version"));
tag_names.insert(kFlashpixVersion, tr("Flashpix Version"));
tag_names.insert(kColorSpace, tr("Color Space"));
tag_names.insert(kComponentsConfiguration, tr("Components Configuration"));
tag_names.insert(kCompressedBitsPerPixel, tr("Compressed Bits Per Pixel"));
tag_names.insert(kPixelXDimension, tr("Pixel X Dimension"));
tag_names.insert(kPixelYDimension, tr("Pixel Y Dimension"));
tag_names.insert(kMakerNote, tr("Maker Note"));
tag_names.insert(kUserComment, tr("User Comment"));
tag_names.insert(kRelatedSoundFile, tr("Related Sound File"));
tag_names.insert(kDateTimeOriginal, tr("Date Time Original"));
tag_names.insert(kDateTimeDigitized, tr("Date Time Digitized"));
tag_names.insert(kSubSecTime, tr("Sub Sec Time"));
tag_names.insert(kSubSecTimeOriginal, tr("Sub Sec Time Original"));
tag_names.insert(kSubSecTimeDigitized, tr("Sub Sec Time Digitized"));
tag_names.insert(kExposureTime, tr("Exposure Time"));
tag_names.insert(kFNumber, tr("F Number"));
tag_names.insert(kExposureProgram, tr("Exposure Program"));
tag_names.insert(kSpectralSensitivity, tr("Spectral Sensitivity"));
tag_names.insert(kISOSpeedRatings, tr("ISO Speed Rating"));
tag_names.insert(kOECF, tr("Optoelectric conversion factor"));
tag_names.insert(kShutterSpeedValue, tr("Shutter Speed"));
tag_names.insert(kApertureValue, tr("Aperture Value"));
tag_names.insert(kBrightnessValue, tr("Brightness"));
tag_names.insert(kExposureBiasValue, tr("Exposure Bias"));
tag_names.insert(kMaxApertureValue, tr("Maximum Lens Aperture"));
tag_names.insert(kSubjectDistance, tr("Subject Distance"));
tag_names.insert(kMeteringMode, tr("Metering Mode"));
tag_names.insert(kLightSource, tr("Light Source"));
tag_names.insert(kFlash, tr("Flash"));
tag_names.insert(kFocalLength, tr("Focal Length"));
tag_names.insert(kSubjectArea, tr("Subject Area"));
tag_names.insert(kFlashEnergy, tr("Flash Energy"));
tag_names.insert(kSpatialFrequencyResponse,
tr("Spatial Frequency Response"));
tag_names.insert(kFocalPlaneXResolution, tr("Focal Plane X Resolution"));
tag_names.insert(kFocalPlaneYResolution, tr("Focal Plane Y Resolution"));
tag_names.insert(kFocalPlaneResolutionUnit,
tr("Focal Plane Resolution Unit"));
tag_names.insert(kSubjectLocation, tr("Subject Location"));
tag_names.insert(kExposureIndex, tr("Exposure Index"));
tag_names.insert(kSensingMethod, tr("Sensing Method"));
tag_names.insert(kFileSource, tr("File Source"));
tag_names.insert(kSceneType, tr("Scene Type"));
tag_names.insert(kCFAPattern, tr("CFA Pattern"));
tag_names.insert(kCustomRendered, tr("Custom Rendered"));
tag_names.insert(kExposureMode, tr("Exposure Mode"));
tag_names.insert(kWhiteBalance, tr("White Balance"));
tag_names.insert(kDigitalZoomRatio, tr("Digital Zoom Ratio"));
tag_names.insert(kFocalLengthIn35mmFilm, tr("Focal Length In 35mm Film"));
tag_names.insert(kSceneCaptureType, tr("Scene Capture Type"));
tag_names.insert(kGainControl, tr("Gain Control"));
tag_names.insert(kContrast, tr("Contrast"));
tag_names.insert(kSaturation, tr("Saturation"));
tag_names.insert(kSharpness, tr("Sharpness"));
tag_names.insert(kDeviceSettingDescription,
tr("Device Setting Description"));
tag_names.insert(kSubjectDistanceRange, tr("Subject Distance Range"));
tag_names.insert(kImageUniqueID, tr("Image Unique ID"));
// The attribute information recorded in the GPS Info IFD.
tag_names.insert(kGPSVersionID, tr("GPS Version ID"));
tag_names.insert(kGPSLatitudeRef, tr("GPS Latitude Ref"));
tag_names.insert(kGPSLatitude, tr("GPS Latitude"));
tag_names.insert(kGPSLongitudeRef, tr("GPS Longitude Ref"));
tag_names.insert(kGPSLongitude, tr("GPS Longitude"));
tag_names.insert(kGPSAltitudeRef, tr("GPS Altitude Ref"));
tag_names.insert(kGPSAltitude, tr("GPS Altitude"));
tag_names.insert(kGPSTimeStamp, tr("GPS Time Stamp"));
tag_names.insert(kGPSSatellites, tr("GPS Satellites"));
tag_names.insert(kGPSStatus, tr("GPS Status"));
tag_names.insert(kGPSMeasureMode, tr("GPS Measure Mode"));
tag_names.insert(kGPSDOP, tr("GPS DOP"));
tag_names.insert(kGPSSpeedRef, tr("GPS Speed Ref"));
tag_names.insert(kGPSSpeed, tr("GPS Speed"));
tag_names.insert(kGPSTrackRef, tr("GPS Track Ref"));
tag_names.insert(kGPSTrack, tr("GPS Track"));
tag_names.insert(kGPSImgDirectionRef, tr("GPS Img Direction Ref"));
tag_names.insert(kGPSImgDirection, tr("GPS Img Direction"));
tag_names.insert(kGPSMapDatum, tr("GPS Map Datum"));
tag_names.insert(kGPSDestLatitudeRef, tr("GPS Dest Latitude Ref"));
tag_names.insert(kGPSDestLatitude, tr("GPS Dest Latitude"));
tag_names.insert(kGPSDestLongitudeRef, tr("GPS Dest Longitude Ref"));
tag_names.insert(kGPSDestLongitude, tr("GPS Dest Longitude"));
tag_names.insert(kGPSDestBearingRef, tr("GPS Dest Bearing Ref"));
tag_names.insert(kGPSDestBearing, tr("GPS Dest Bearing"));
tag_names.insert(kGPSDestDistanceRef, tr("GPS Dest Distance Ref"));
tag_names.insert(kGPSDestDistance, tr("GPS Dest Distance"));
tag_names.insert(kGPSProcessingMethod, tr("GPS Processing Method"));
tag_names.insert(kGPSAreaInformation, tr("GPS Area Information"));
tag_names.insert(kGPSDateStamp, tr("GPS Date Stamp"));
tag_names.insert(kGPSDifferential, tr("GPS Differential"));
set_tag_names(tag_names);
}
// Reads all IFDs from the specified ifd_offset and saved
void Exif::ReadIfds(int ifd_offset) {
tiff_header()->ToIfd(ifd_offset);
QList<qint64> ifd_offsets;
// Reads a sequence of 12-byte field entries.
while (tiff_header()->HasNextIfdEntry()) {
qint64 ifd_entry_offset = tiff_header()->NextIfdEntryOffset();
Tag tag = static_cast<Tag>(tiff_header()->IfdEntryTag(ifd_entry_offset));
if (!tag_names().contains(tag))
continue;
QHash<Tag, qint64> offsets = tag_offsets();
offsets.insert(tag, ifd_entry_offset);
set_tag_offsets(offsets);
if (tag == kExifIfdPointer || tag == kGpsInfoIfdPointer) {
QByteArray entry_value = tiff_header()->IfdEntryValue(ifd_entry_offset);
qint64 ifd_pointer_offset = entry_value.toHex().toUInt(NULL, 16) +
tiff_header()->file_start_offset();
ifd_offsets.append(ifd_pointer_offset);
}
}
for (int i = 0; i < ifd_offsets.count(); ++i) {
ReadIfds(ifd_offsets.at(i));
}
}
// Returns the byte data of the thumbnail saved in Exif.
QByteArray Exif::Thumbnail() {
QByteArray thumbnail;
quint32 thumbnail_offset = Value(kJPEGInterchangeFormat).ToUInt();
quint32 length = Value(kJPEGInterchangeFormatLength).ToUInt();
if (thumbnail_offset && length) {
thumbnail_offset += tiff_header()->file_start_offset();
file()->seek(thumbnail_offset);
thumbnail = file()->read(length);
}
return thumbnail;
}
// Returns the value of the specified tag as a ExifData.
ExifData Exif::Value(Tag tag) {
QByteArray value;
if (tag_offsets().contains(tag))
value = tiff_header()->IfdEntryValue(tag_offsets().value(tag));
ExifData exif_data(value);
return exif_data;
}
} // namespace qmeta

View File

@ -1,67 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the details of all classes related to Exif data.
#include "qmeta/exif_data.h"
#include <QtCore>
namespace qmeta {
ExifData::ExifData(const QByteArray &other) : QByteArray(other) {}
// Returns the byte array converted to double. This function works correctly
// if the Type is RATIONAL and the Count is 1.
double ExifData::ToDouble() {
double numerator = static_cast<double>(mid(0,4).toHex().toUInt(NULL, 16));
double denominator = static_cast<double>(mid(4).toHex().toUInt(NULL, 16));
return numerator/ denominator;
}
// Returns the byte array converted to float. This function works correctly
// if the Type is SRATIONAL and the Count is 1.
float ExifData::ToFloat() {
float numerator = static_cast<float>(mid(0,4).toHex().toInt(NULL, 16));
float denominator = static_cast<float>(mid(4).toHex().toInt(NULL, 16));
return numerator/ denominator;
}
// Returns the byte array converted to int in decimal. This function works
// correctly if the Type is one of BYTE, SHORT, or SLONG and the Count is 1.
int ExifData::ToInt() {
return toHex().toInt(NULL, 16);
}
// Returns the byte array converted to QString. This functions works correctly
// if the Type is ASCII.
QString ExifData::ToString() {
return QString(data());
}
// Returns the byte array converted to uint in decimal. This function works
// correctly if the Type is BYTE, SHORT, or LONG and the Count is 1.
uint ExifData::ToUInt() {
return toHex().toUInt(NULL, 16);
}
} // namespace qmeta

View File

@ -1,84 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the File class.
#include "qmeta/file.h"
#include <QtCore>
#include "qmeta/exif.h"
namespace qmeta {
// Constructs a file from the given QByteArray data.
File::File(QByteArray *data) {
set_exif(NULL);
set_iptc(NULL);
set_xmp(NULL);
QBuffer *file = new QBuffer(data, this);
if (file->open(QIODevice::ReadOnly))
set_file(file);
else
set_file(NULL);
}
// Constructs a file from the given QIODevice file.
File::File(QIODevice *file) {
set_exif(NULL);
set_iptc(NULL);
set_xmp(NULL);
set_file(file);
}
// Constructs a file and tries to load the file with the given file_name.
File::File(const QString &file_name) {
set_exif(NULL);
set_iptc(NULL);
set_xmp(NULL);
QFile *file = new QFile(file_name, this);
if (file->open(QIODevice::ReadOnly))
set_file(file);
else
set_file(NULL);
}
// Returns the thumbnail from supported metadata. Currently Exif is the only
// supported metadata.
QByteArray File::Thumbnail() {
QByteArray thumbnail;
if (exif())
thumbnail = exif()->Thumbnail();
return thumbnail;
}
// Initializes metadata objects for the tracked file.
void File::InitMetadata() {
if (!IsValid())
return;
InitExif();
InitIptc();
InitXmp();
}
} // namespace qmeta

View File

@ -1,85 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the Image class.
#include "qmeta/image.h"
#include <QtCore>
namespace qmeta {
Image::Image(QByteArray *data) : File(data) {
GuessType();
}
Image::Image(QIODevice *file) : File(file) {
GuessType();
}
Image::Image(const QString &file_name) : File(file_name) {
GuessType();
}
// Guesses the file type of the tracked file. It calls the GuessType(FileType)
// function for all file types it guesses. If there is no matched file type
// or there is no tracked file object, sets the file type to kInvalidFileType.
void Image::GuessType() {
if (file()) {
// Guess the file type as JPEG.
if (GuessType<Jpeg>(kJpegFileType))
return;
// Guess the file type as Tiff.
else if (GuessType<Tiff>(kTiffFileType))
return;
}
set_file_type(kInvalidFileType);
}
// Guesses the file type of the tracked file. Tries to creates a new image
// object using the specified type T, if the image is valid, sets the specified
// file_type to current file type and binds the image's metadata objects.
// Returns true if the specified type T is correct.
template<class T> bool Image::GuessType(FileType file_type) {
T *image = new T(file());
if (image->IsValid()) {
image->setParent(this);
set_file_type(file_type);
set_exif(image->exif());
set_iptc(image->iptc());
set_xmp(image->xmp());
return true;
} else {
delete image;
return false;
}
}
// Reimplements the File::IsValid().
bool Image::IsValid() {
if (file_type() == kInvalidFileType)
return false;
else
return true;
}
}

View File

@ -1,189 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the Iptc class.
#include "qmeta/iptc.h"
#include <QtCore>
namespace qmeta {
Iptc::Iptc(QObject *parent) : Standard(parent) {
InitRepeatableTags();
InitTagNames();
}
// Initializes the IPTC object. Returns false if no valid tag is found.
bool Iptc::Init(QIODevice *file, const qint64 file_start_offset) {
set_file(file);
set_file_start_offset(file_start_offset);
return ReadRecord();
}
// Adds all repeatable tags to the repeatable_tags_ property.
void Iptc::InitRepeatableTags() {
QList<Tag> repeatable_tags;
repeatable_tags.append(kObjectAttributeReference);
repeatable_tags.append(kSubjectReference);
repeatable_tags.append(kSupplementalCategory);
repeatable_tags.append(kKeywords);
repeatable_tags.append(kContentLocationCode);
repeatable_tags.append(kContentLocationName);
repeatable_tags.append(kReferenceService);
repeatable_tags.append(kReferenceDate);
repeatable_tags.append(kReferenceNumber);
repeatable_tags.append(kByLine);
repeatable_tags.append(kByLineTitle);
repeatable_tags.append(kContact);
repeatable_tags.append(kWriterEditor);
set_repeatable_tags(repeatable_tags);
}
// Initializes tag names used in IPTC.
void Iptc::InitTagNames() {
QHash<Tag, QString> tag_names;
tag_names.insert(kRecordVersion, tr("Record Version"));
tag_names.insert(kObjectTypeReference, tr("Object Type Reference"));
tag_names.insert(kObjectAttributeReference, tr("Object Attribute Reference"));
tag_names.insert(kObjectName, tr("Object Name"));
tag_names.insert(kEditStatus, tr("Edit Status"));
tag_names.insert(kEditorialUpdate, tr("Editorial Update"));
tag_names.insert(kUrgency, tr("Urgency"));
tag_names.insert(kSubjectReference, tr("Subject Reference"));
tag_names.insert(kCategory, tr("Category"));
tag_names.insert(kSupplementalCategory, tr("Supplemental Category"));
tag_names.insert(kFixtureIdentifier, tr("Fixture Identifier"));
tag_names.insert(kKeywords, tr("Keywords"));
tag_names.insert(kContentLocationCode, tr("Content Location Code"));
tag_names.insert(kContentLocationName, tr("Content Location Name"));
tag_names.insert(kReleaseDate, tr("Release Date"));
tag_names.insert(kReleaseTime, tr("Release Time"));
tag_names.insert(kExpirationDate, tr("Expiration Date"));
tag_names.insert(kExpirationTime, tr("Expiration Time"));
tag_names.insert(kSpecialInstructions, tr("Special Instructions"));
tag_names.insert(kActionAdvised, tr("Action Advised"));
tag_names.insert(kReferenceService, tr("Reference Service"));
tag_names.insert(kReferenceDate, tr("Reference Date"));
tag_names.insert(kReferenceNumber, tr("Reference Number"));
tag_names.insert(kDateCreated, tr("Date Created"));
tag_names.insert(kTimeCreated, tr("Time Created"));
tag_names.insert(kDigitalCreationDate, tr("Digital Creation Date"));
tag_names.insert(kDigitalCreationTime, tr("Digital Creation Time"));
tag_names.insert(kOriginatingProgram, tr("Originating Program"));
tag_names.insert(kProgramVersion, tr("Program Version"));
tag_names.insert(kObjectCycle, tr("Object Cycle"));
tag_names.insert(kByLine, tr("By Line"));
tag_names.insert(kByLineTitle, tr("By Line Title"));
tag_names.insert(kCity, tr("City"));
tag_names.insert(kSubLocation, tr("Sub Location"));
tag_names.insert(kProvinceState, tr("Province State"));
tag_names.insert(kCountryPrimaryLocationCode,
tr("Country Primary Location Code"));
tag_names.insert(kCountryPrimaryLocationName,
tr("Country Primary Location Name"));
tag_names.insert(kOriginalTransmissionReference,
tr("Original Transmission Reference"));
tag_names.insert(kHeadline, tr("Headline"));
tag_names.insert(kCredit, tr("Credit"));
tag_names.insert(kSource, tr("Source"));
tag_names.insert(kCopyrightNotice, tr("Copyright Notice"));
tag_names.insert(kContact, tr("Contact"));
tag_names.insert(kCaptionAbstract, tr("Caption Abstract"));
tag_names.insert(kWriterEditor, tr("Writer Editor"));
tag_names.insert(kRasterizedCaption, tr("Rasterized Caption"));
tag_names.insert(kImageType, tr("Image Type"));
tag_names.insert(kImageOrientation, tr("Image Orientation"));
tag_names.insert(kLanguageIdentifier, tr("Language Identifier"));
tag_names.insert(kAudioType, tr("Audio Type"));
tag_names.insert(kAudioSamplingRate, tr("Audio Sampling Rate"));
tag_names.insert(kAudioSamplingResolution, tr("Audio Sampling Resolution"));
tag_names.insert(kAudioDuration, tr("Audio Duration"));
tag_names.insert(kAudioOutcue, tr("Audio Outcue"));
tag_names.insert(kObjDataPreviewFileFormat,
tr("Object Data Preview File Format"));
tag_names.insert(kObjDataPreviewFileFormatVer,
tr("Object Data Preview File Format Version"));
tag_names.insert(kObjDataPreviewData, tr("Object Data Preview Data"));
set_tag_names(tag_names);
}
// Reads the DataSet started from the specified offset.
QByteArray Iptc::ReadDataSet(int offset) {
QByteArray data;
file()->seek(offset);
Tag tag = static_cast<Tag>(file()->read(1).toHex().toInt(NULL, 16));
if (!tag_names().contains(tag))
return data;
int size = file()->read(2).toHex().toInt(NULL, 16);
data = file()->read(size);
return data;
}
// Reads the Record started from the specified offset. Also saves all found
// tags and their offsets in the tag_offsets_ property. Returns false if
// no tag is found.
bool Iptc::ReadRecord() {
file()->seek(file_start_offset());
QHash<Tag, qint64> tag_offsets;
while (file()->read(2).toHex() == "1c02") {
qint64 tag_offset = file()->pos();
Tag tag = static_cast<Tag>(file()->read(1).toHex().toInt(NULL, 16));
QByteArray data = ReadDataSet(tag_offset);
if (repeatable_tags().contains(tag))
tag_offsets.insertMulti(tag, tag_offset);
else
tag_offsets.insert(tag, tag_offset);
}
// Returns false if no valid tag is found.
if (tag_offsets.count() == 0)
return false;
set_tag_offsets(tag_offsets);
return true;
}
// Returns the value associated with the specified tag.
QByteArray Iptc::Value(Tag tag) {
QByteArray value;
if (tag_offsets().contains(tag)) {
int offset = tag_offsets().value(tag);
value = ReadDataSet(offset);
}
return value;
}
// Returns a lit containing all the values associated with the specified tag.
QList<QByteArray> Iptc::Values(Tag tag) {
QList<QByteArray> values;
QList<qint64> offsets = tag_offsets().values(tag);
for (int i = 0; i < offsets.count(); ++i) {
qint64 offset = offsets.at(i);
QByteArray value = ReadDataSet(offset);
values.append(value);
}
qSort(values);
return values;
}
} // namespace qmeta

View File

@ -1,181 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate file_types metadata based on Qt.
//
// This file implements the detail of the Jpeg class.
#include "qmeta/jpeg.h"
#include <QtCore>
#include <qitty/byte_array.h>
#include "qmeta/exif.h"
#include "qmeta/iptc.h"
#include "qmeta/tiff_header.h"
#include "qmeta/xmp.h"
namespace qmeta {
Jpeg::Jpeg(QByteArray *data) : File(data) {
InitMetadata();
}
Jpeg::Jpeg(QIODevice *file) : File(file) {
InitMetadata();
}
Jpeg::Jpeg(const QString &file_name) : File(file_name) {
InitMetadata();
}
// Reimplements the File::IsValid().
bool Jpeg::IsValid() {
if (!file())
return false;
// Checks the first 2 bytes if equals to the SOI marker.
file()->seek(0);
if (file()->read(2).toHex() != "ffd8")
return false;
return true;
}
// Reimplements the File::InitExif().
void Jpeg::InitExif() {
file()->seek(2);
while (!file()->atEnd()) {
// Finds APP1 marker.
if (file()->read(1).toHex() != "ff")
continue;
if (file()->read(1).toHex() != "e1")
continue;
// Retrieves the APP1 length. The length doesn't include the APP1 marker.
file()->read(2).toHex().toInt(NULL, 16);
// Checks the Exif signature.
if (QString(file()->read(6)) == "Exif")
break;
}
if (file()->atEnd())
return;
TiffHeader *tiff_header = new TiffHeader(this);
if (tiff_header->Init(file(), file()->pos())) {
// Creates the Exif object.
Exif *exif = new Exif(this);
if (exif->Init(file(), tiff_header))
set_exif(exif);
else
delete exif;
} else {
delete tiff_header;
}
}
// Reimplements the File::InitIptc().
void Jpeg::InitIptc() {
// Finds the APP13 marker.
file()->seek(2);
while (!file()->atEnd()) {
if (file()->read(1).toHex() != "ff")
continue;
if (file()->read(1).toHex() != "ed")
continue;
break;
}
// Returns if there is not APP13 marker.
if (file()->atEnd())
return;
// Skips segment size marker.
file()->read(2);
// Checks the Photoshop signature.
if (QString(file()->read(14)) != "Photoshop 3.0")
return;
bool found_iptc = false;
// Interators the Image Resource Blocks to find IPTC data. If found, sets the
// `found_iptc` to true and gets out of the loop.
while (QString(file()->read(4)) == "8BIM") {
int identifier = file()->read(2).toHex().toInt(NULL, 16);
// Skips the variable name in Pascal string, padded to make the size even.
// A null name consists of two bytes of 0.
int name_length = file()->read(1).toHex().toInt(NULL, 16);
if (name_length == 0)
file()->read(1);
else if (name_length % 2 == 1)
file()->read(name_length);
else
file()->read(name_length + 1);
// Determines the actual size of resource data that follows.
int data_length = file()->read(4).toHex().toInt(NULL, 16);
// Determines if the current block is used to record the IPTC data.
// If true, the identifier should be 1028 in decimal.
if (identifier == 1028) {
found_iptc = true;
break;
} else {
file()->read(data_length);
}
}
// Returns if there is no IPTC data.
if (!found_iptc)
return;
// Creates the Iptc object.
Iptc *iptc = new Iptc(this);
if (iptc->Init(file(), file()->pos()))
set_iptc(iptc);
else
delete iptc;
}
// Reimplements the File::InitXmp().
void Jpeg::InitXmp() {
file()->seek(2);
while (!file()->atEnd()) {
// Finds APP1 marker.
if (file()->read(1).toHex() != "ff")
continue;
if (file()->read(1).toHex() != "e1")
continue;
// Retrieves the APP1 length. The length doesn't include the APP1 marker.
file()->read(2).toHex().toInt(NULL, 16);
// Checks the XMP signature.
if (QString(file()->read(29)) == "http://ns.adobe.com/xap/1.0/")
break;
}
if (file()->atEnd())
return;
Xmp *xmp = new Xmp(this);
if (xmp->Init(file(), file()->pos()))
set_xmp(xmp);
else
delete xmp;
}
} // namespace qmeta

View File

@ -1,33 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the Standard class.
#include "qmeta/standard.h"
#include <QtCore>
namespace qmeta {
Standard::Standard(QObject *parent) : QObject(parent) {}
} // namespace qmeta

View File

@ -1,138 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the TIFF class.
#include "qmeta/tiff.h"
#include <QtCore>
#include <qitty/byte_array.h>
#include "qmeta/exif.h"
#include "qmeta/iptc.h"
#include "qmeta/tiff_header.h"
#include "qmeta/xmp.h"
namespace qmeta {
Tiff::Tiff(QByteArray *data) : File(data) {
Init();
}
Tiff::Tiff(QIODevice *file) : File(file) {
Init();
}
Tiff::Tiff(const QString &file_name) : File(file_name) {
Init();
}
// Initializes the Tiff object.
void Tiff::Init() {
if (!file())
return;
TiffHeader *tiff_header = new TiffHeader(this);
if (tiff_header->Init(file(), 0))
set_tiff_header(tiff_header);
else
set_tiff_header(NULL);
InitMetadata();
}
// Reimplements the File::IsValid().
bool Tiff::IsValid() {
if (!file())
return false;
if (tiff_header())
return true;
else
return false;
}
// Reimplements the File::InitExif().
void Tiff::InitExif() {
if (tiff_header()) {
// Creates the Exif object.
Exif *exif = new Exif(this);
if (exif->Init(file(), tiff_header()))
set_exif(exif);
else
delete exif;
}
}
// Reimplements the File::InitIptc().
void Tiff::InitIptc() {
tiff_header()->ToFirstIfd();
// Creates a variable used to save the offset of the IPTC data. This value
// will be overwritten if the IPTC data is found.
qint64 iptc_offset = -1;
// Finds the IPTC data from the TIFF header. IPTC offset is recorded in
// the "IPTC dataset" tag, and represented as 33723 in decimal.
while (tiff_header()->HasNextIfdEntry()) {
qint64 ifd_entry_offset = tiff_header()->NextIfdEntryOffset();
int tag = tiff_header()->IfdEntryTag(ifd_entry_offset);
if (tag == 33723) {
iptc_offset = tiff_header()->IfdEntryOffset(ifd_entry_offset);
break;
}
}
if (iptc_offset != -1) {
// Creates the Iptc object.
Iptc *iptc = new Iptc(this);
if (iptc->Init(file(), iptc_offset))
set_iptc(iptc);
else
delete iptc;
}
}
// Reimplements the File::InitXmp().
void Tiff::InitXmp() {
tiff_header()->ToFirstIfd();
// Creates a variable used to save the offset of the XMP packet. This value
// will be overwritten if the XMP packet is found.
qint64 xmp_offset = -1;
// Finds the XMP packet from the TIFF header. XMP offset is recorded in
// the "XMP packet" tag, and represented as 700 in decimal.
while (tiff_header()->HasNextIfdEntry()) {
qint64 ifd_entry_offset = tiff_header()->NextIfdEntryOffset();
int tag = tiff_header()->IfdEntryTag(ifd_entry_offset);
if (tag == 700) {
xmp_offset = tiff_header()->IfdEntryOffset(ifd_entry_offset);
break;
}
}
if (xmp_offset != -1) {
// Creates the Xmp object.
Xmp *xmp = new Xmp(this);
if (xmp->Init(file(), xmp_offset))
set_xmp(xmp);
else
delete xmp;
}
}
} // namespace qmeta

View File

@ -1,207 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the TiffHeader class.
#include "qmeta/tiff_header.h"
#include <QtCore>
#include <qitty/byte_array.h>
namespace qmeta {
TiffHeader::TiffHeader(QObject *parent) : QObject(parent) {
InitTypeByteUnit();
}
// Returns true if next IFD entry exists.
bool TiffHeader::HasNextIfdEntry() {
if (current_entry_number() < current_entry_count())
return true;
else
return false;
}
// Returns the Tag of the entry at the specified entry_offset in decimal.
int TiffHeader::IfdEntryTag(qint64 ifd_entry_offset) {
file()->seek(ifd_entry_offset);
return ReadFromFile(2).toHex().toInt(NULL, 16);
}
// Returns the Type of the entry at the specified entry_offset.
TiffHeader::Type TiffHeader::IfdEntryType(qint64 ifd_entry_offset) {
file()->seek(ifd_entry_offset + 2);
return static_cast<Type>(ReadFromFile(2).toHex().toInt(NULL, 16));
}
// Returns the value of the entry at the specified entry_offset. Note that
// the returned value is always in the big-endian byte order.
QByteArray TiffHeader::IfdEntryValue(qint64 ifd_entry_offset) {
Type type = IfdEntryType(ifd_entry_offset);
int count = ReadFromFile(4).toHex().toInt(NULL, 16);
// Retrieves the byte unit of the specified type.
int current_type_byte_unit = type_byte_unit().value(type);
// Calculates the number of bytes used for the entry value.
int value_byte_count = current_type_byte_unit * count;
// Jumps to the offset containing the entry value if the byte count > 4.
if (value_byte_count > 4) {
qint64 offset = ReadFromFile(4).toHex().toInt(NULL, 16) +
file_start_offset();
file()->seek(offset);
}
QByteArray value;
if (current_type_byte_unit == 1) {
value = file()->read(value_byte_count);
} else {
for (int i = 0; i < count; ++i) {
// If the specified type is RATIONAL or SRATIONAL, read 4 bytes twice
// for double LONG or double SLONG, respectively.
if (current_type_byte_unit == 8) {
value.append(ReadFromFile(4));
value.append(ReadFromFile(4));
} else {
value.append(ReadFromFile(current_type_byte_unit));
}
}
}
return value;
}
// Returns the value offset for the IFD entry at the specified ifd_entry_offset.
// Returns -1 if the if the value is not an offset.
qint64 TiffHeader::IfdEntryOffset(qint64 ifd_entry_offset) {
Type type = IfdEntryType(ifd_entry_offset);
int count = ReadFromFile(4).toHex().toInt(NULL, 16);
// Retrieves the byte unit of the specified type.
int current_type_byte_unit = type_byte_unit().value(type);
// Calculates the number of bytes used for the entry value.
int value_byte_count = current_type_byte_unit * count;
// Jumps to the offset containing the entry value if the byte count > 4.
if (value_byte_count > 4) {
qint64 offset = ReadFromFile(4).toHex().toInt(NULL, 16) +
file_start_offset();
return offset;
} else {
return -1;
}
}
// Initializes the TiffHeader object. Returns true if successful.
bool TiffHeader::Init(QIODevice *file, qint64 file_start_offset) {
set_file(file);
file->seek(file_start_offset);
// Determines the byte order in the specified file.
QByteArray byte_order = file->read(2);
if (byte_order == "II")
set_endianness(kLittleEndians);
else if (byte_order == "MM")
set_endianness(kBigEndians);
else
return false;
// Further identifies whether the specified file has a valid TIFF header.
// Reads the next two bytes which should have the value of 42 in decimal.
if (ReadFromFile(2).toHex().toInt(NULL, 16) != 42)
return false;
// Reads the next four bytes to determine the offset of the first IFD.
int first_ifd_offset = ReadFromFile(4).toHex().toInt(NULL, 16);
// Sets the offset to the current position if the read value equals to 8.
// The reason is for JPEG files, if the TIFF header is followed immediately
// by the first IFD, it is written as 00000008 in hexidecimal.
if (first_ifd_offset == 8)
first_ifd_offset = file->pos();
// Sets properties.
set_file_start_offset(file_start_offset);
set_first_ifd_offset(first_ifd_offset);
// Jumps to the first IFD by default.
ToFirstIfd();
return true;
}
// Initializes the type_byte_unit_ property.
void TiffHeader::InitTypeByteUnit() {
QHash<Type, int> type_byte_unit;
type_byte_unit.insert(kByteType, 1);
type_byte_unit.insert(kAsciiType, 1);
type_byte_unit.insert(kShortType, 2);
type_byte_unit.insert(kLongType, 4);
type_byte_unit.insert(kRationalType, 8);
type_byte_unit.insert(kSByte, 1);
type_byte_unit.insert(kUndefinedType, 1);
type_byte_unit.insert(kSShort, 2);
type_byte_unit.insert(kSLongType, 4);
type_byte_unit.insert(kSRationalType, 8);
type_byte_unit.insert(kFloat, 4);
type_byte_unit.insert(kDouble, 8);
set_type_byte_unit(type_byte_unit);
}
// Returns the offset of the next IFD entry and increases the entry offset.
// Returns -1 if there is no further IFD entry.
qint64 TiffHeader::NextIfdEntryOffset() {
if (current_entry_number() == current_entry_count())
return -1;
qint64 entry_offset = current_ifd_offset() + 2 + current_entry_number() * 12;
// Increases the current entry number by 1.
set_current_entry_number(current_entry_number() + 1);
// If already reaches the end of the current IFD. Jumps to the next IFD if
// available.
if (current_entry_number() == current_entry_count()) {
file()->seek(current_ifd_offset() + 2 + current_entry_count() * 12);
qint64 next_ifd_offset = ReadFromFile(4).toHex().toInt(NULL, 16);
if (next_ifd_offset != 0)
ToIfd(next_ifd_offset + file_start_offset());
}
return entry_offset;
}
// Reads at most max_size bytes from the tracked file object, and returns the
// data read as a QByteArray in big-endian byte order.
QByteArray TiffHeader::ReadFromFile(const int max_size) {
QByteArray data = file()->read(max_size);
if (endianness() == kLittleEndians)
data = qitty_utils::ReverseByteArray(data);
return data;
}
// Jumps to the offset of the first IFD and sets the current_entry_number_ and
// the entry_count_ properties.
void TiffHeader::ToFirstIfd() {
ToIfd(first_ifd_offset());
}
// Jumps to the IFD at specified offset and sets the current_entry_number_ and
// the entry_count_ properties. The specified offset must point to the beginning
// of a valid IFD.
void TiffHeader::ToIfd(qint64 offset) {
file()->seek(offset);
set_current_ifd_offset(offset);
set_current_entry_count(ReadFromFile(2).toHex().toInt(NULL, 16));
set_current_entry_number(0);
}
} // namespace qmeta

View File

@ -1,41 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// Implements utility functions for Qt's QByteArray class.
#include "qitty/byte_array.h"
#include <QByteArray>
namespace qitty_utils {
// Reverses the order of data in the specified byte_array.
QByteArray ReverseByteArray(QByteArray byte_array) {
QByteArray reversed_byte_array;
while (byte_array.count()) {
reversed_byte_array.append(byte_array.right(1).at(0));
byte_array.chop(1);
}
return reversed_byte_array;
}
} // namespace qitty_utils

View File

@ -1,56 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
#include "qitty/image.h"
#include <QImage>
#include <QImageReader>
#include <QString>
namespace qitty_utils {
// Returns an image with the given length and tries to load the image from the
// file with the given file_name.
QImage SacledImage(const QString &file_name, int length) {
QImageReader image_reader(file_name);
if (!image_reader.canRead()) {
QImage image;
return image;
}
int image_width = image_reader.size().width();
int image_height = image_reader.size().height();
if (image_width > image_height) {
image_height = static_cast<double>(length) / image_width * image_height;
image_width = length;
} else if (image_width < image_height) {
image_width = static_cast<double>(length) / image_height * image_width;
image_height = length;
} else {
image_width = length;
image_height = length;
}
image_reader.setScaledSize(QSize(image_width, image_height));
return image_reader.read();
}
} // namespace qitty_utils

View File

@ -1,40 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
#include "qitty/style_sheet.h"
#include <QFile>
#include <QIODevice>
#include <QString>
#include <QWidget>
namespace qitty_utils {
// Sets the style sheet of the specified widget from the specified file path.
void SetStyleSheet(QWidget *widget, const QString &path) {
QFile file(path);
file.open(QIODevice::ReadOnly);
widget->setStyleSheet(QString(file.readAll().constData()));
file.close();
}
} // namespace qitty_utils

View File

@ -1,95 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// This file implements the detail of the LineEdit class.
#include "qitty/line_edit.h"
#include <QtGui>
namespace qitty_widgets {
// Constructs a line edit with no text.
LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) {
Init();
}
// Constructs a line edit containing the text `contents`.
LineEdit::LineEdit(const QString &contents, QWidget *parent) :
QLineEdit(contents, parent) {
Init();
}
// Clears focus if the clear_focus_when_return_pressed_ property is set to true.
void LineEdit::ClearFocusWhenReturnPressed() {
if (clear_focus_when_return_pressed())
clearFocus();
}
// Reimplements the QLineEdit::focusInEvent() function.
void LineEdit::focusInEvent(QFocusEvent *event) {
// Clears the text if the hint is set.
if (!hint().isNull())
setText("");
QLineEdit::focusInEvent(event);
}
// Reimplements the QLineEdit::focusOutEvent() function.
void LineEdit::focusOutEvent(QFocusEvent *event) {
// Emits the FocusOut() signal.
emit FocusOut();
// Sets the text to the hint if the hint is set.
if (!hint().isNull())
setText(hint());
QLineEdit::focusOutEvent(event);
}
// Initializes the LineEdit object. This function should be called in all
// constructors.
void LineEdit::Init() {
set_clear_focus_when_return_pressed(false);
set_is_modified(false);
// Updates the is_modified_ property using the modificationChanged() signal.
connect(this, SIGNAL(textEdited(const QString)),
this, SLOT(SetModifiedToTrue()));
// Clears focus when the Return or the Enter key pressed if the
// clear_focus_when_return_pressed_ is set to true.
connect(this, SIGNAL(returnPressed()),
this, SLOT(ClearFocusWhenReturnPressed()));
}
// Sets the hint, also sets the text if the widget doesn't have focus.
void LineEdit::SetHint(const QString &hint) {
set_hint(hint);
if (!hasFocus())
setText(hint);
}
// [slot] Sets the is_modified_ property to true.
void LineEdit::SetModifiedToTrue() {
set_is_modified(true);
}
} // namespace qitty_widgets

View File

@ -1,203 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of Qitty.
//
// Qitty is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// Qitty is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with Qitty. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// Qitty - a toolkit to enhance the Qt library.
//
// This file implements the detail of the PlainTextEdit class.
#include "qitty/plain_text_edit.h"
#include <QtGui>
#include "qitty/style_sheet.h"
namespace qitty_widgets {
// Constructs an PlainTextEdit with `mode` and `parent`.
PlainTextEdit::PlainTextEdit(Mode mode, QWidget *parent) :
QPlainTextEdit(parent) {
Init(mode);
}
// Reimplements the QPlainTextEdit::focusInEvent() function.
void PlainTextEdit::focusInEvent(QFocusEvent *event) {
// Clears the cursor. The width of the cursor will be recovered in the
// keyPressEvent() and the mousePressEvent() functions.
setCursorWidth(0);
// Selects all text. This step is trying to simulates the effect of the
// QLineEdit widget whenever the focus moves in to the widget by the Tab key.
selectAll();
QPlainTextEdit::focusInEvent(event);
}
// Reimplements the QPlainTextEdit::focusOutEvent() function.
void PlainTextEdit::focusOutEvent(QFocusEvent *event) {
// Clears the selection.
QTextCursor text_cursor = textCursor();
text_cursor.clearSelection();
setTextCursor(text_cursor);
// Emits the FocusOut() signal.
emit FocusOut();
QPlainTextEdit::focusOutEvent(event);
}
// Initializes the PlainTextEdit object. This function should be called
// in all constructors.
void PlainTextEdit::Init(Mode mode) {
setObjectName("plain_text_edit");
qitty_utils::SetStyleSheet(this, ":/qitty/css/plain_text_edit.css");
// Initializes properties.
set_all_selected(false);
set_clear_focus_when_return_pressed(false);
set_initial_cursor_width(cursorWidth());
set_minimum_line_number(3);
// Updates the state of the all_selected_ property whenever selection changed.
connect(this, SIGNAL(selectionChanged()), this, SLOT(UpdateAllSelected()));
// Updates the is_modified_ property using the modificationChanged() signal.
connect(this, SIGNAL(modificationChanged(bool)),
this, SLOT(UpdateModified(bool)));
// Updates the state whenever the mode is changed and keeps the specified
// `mode`
connect(this, SIGNAL(ModeChanged(Mode)), this, SLOT(UpdateModeState(Mode)));
set_mode(mode);
}
// Reimplements the QPlainTextEdit::keyPressEvent() function.
void PlainTextEdit::keyPressEvent(QKeyEvent *event) {
// Clears focus if the clear_focus_when_return_pressed_ property is set to
// true and the Return or the Enter key is pressed.
if (clear_focus_when_return_pressed() &&
(event->key() == 16777220 || event->key() == 16777221)) {
clearFocus();
return;
}
// Recovers the width of the cursor. This step is needed because the cursor
// is cleared in the focusInEvent() function.
RecoverCursorWidth();
// If full text is selected, moves the cursor to the start if left or up
// arrows are pressed, moves to the end if right or bottom arrows are pressed.
if (all_selected()) {
if (event->key() == 16777234 || event->key() == 16777235)
moveCursor(QTextCursor::Start);
else if (event->key() == 16777236 || event->key() == 16777237)
moveCursor(QTextCursor::End);
}
QPlainTextEdit::keyPressEvent(event);
}
// Reimplements the QPlainTextEdit::mousePressEvent() function.
void PlainTextEdit::mousePressEvent(QMouseEvent *event) {
// Recovers the width of the cursor. This step is needed because the cursor
// is cleared in the focusInEvent() function.
RecoverCursorWidth();
// Clears the selection if full text is selected.
if (all_selected()) {
QTextCursor text_cursor = textCursor();
text_cursor.clearSelection();
setTextCursor(text_cursor);
}
QPlainTextEdit::mousePressEvent(event);
}
// Sets the width of the cursor back to the orignal one.
void PlainTextEdit::RecoverCursorWidth() {
setCursorWidth(initial_cursor_width());
}
// Reimplements the QPlainTextEdit::resizeEvent() function.
void PlainTextEdit::resizeEvent(QResizeEvent *event) {
QPlainTextEdit::resizeEvent(event);
// Updates the minimum_height_ property and the hieght of this widget if
// this widget is in the kElasticMode.
if (mode() == kElasticMode) {
UpdateMinimumHeight();
UpdateHeight();
}
}
// Sets the all_selected_ property to true if full text is selected.
void PlainTextEdit::UpdateAllSelected() {
QTextCursor text_cursor = textCursor();
if (text_cursor.selectedText() == toPlainText())
set_all_selected(true);
else
set_all_selected(false);
}
// Calculates the proper height according to the plain text. If the height is
// shorter than the minimum height, sets the height to the minimum height.
// Note that this function is used only in the kElasticMode.
void PlainTextEdit::UpdateHeight() {
// Calculates the proper height according to current plain text.
QFontMetrics font_metrics = fontMetrics();
QRect bounding_rect = font_metrics.boundingRect(0, 0, width() - 6, 0,
Qt::TextWordWrap,
toPlainText());
// Determines the actual height by comparing with the minimum height.
int height = minimum_height();
if (bounding_rect.height() > height)
height = bounding_rect.height();
// Sets the height of this widget. Adds 6 for padding.
setFixedHeight(height + 6);
}
// Calculates the minimum height according to the minimum line number.
// Note that this function is used only in the kElasticMode.
void PlainTextEdit::UpdateMinimumHeight() {
// Creates an empty text to contain minimum lines.
QString text;
for (int i = 1; i < minimum_line_number(); ++i)
text.append(QChar::LineSeparator);
// Calculates the height according to the text.
QFontMetrics font_metrics = fontMetrics();
QRect bounding_rect = font_metrics.boundingRect(0, 0, width(), 0,
Qt::TextWordWrap, text);
set_minimum_height(bounding_rect.height());
}
// [slot] Updates the state according to the specified `mode`.
void PlainTextEdit::UpdateModeState(Mode mode) {
if (mode == kElasticMode) {
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setTabChangesFocus(true);
// // Updates the height of this widget whenever text changed.
connect(this, SIGNAL(textChanged()), this, SLOT(UpdateHeight()));
} else {
disconnect(this, SIGNAL(textChanged()), this, SLOT(UpdateHeight()));
}
}
// [slot] Updates the is_modified_ property by the specified `changed`.
void PlainTextEdit::UpdateModified(bool changed) {
set_is_modified(changed);
}
} // namespace qitty_widgets

View File

@ -1,77 +0,0 @@
// Copyright 2010, Ollix
// All rights reserved.
//
// This file is part of QMeta.
//
// QMeta is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// QMeta is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with QMeta. If not, see <http://www.gnu.org/licenses/>.
// ---
// Author: olliwang@ollix.com (Olli Wang)
//
// QMeta - a library to manipulate image metadata based on Qt.
//
// This file implements the detail of the Xmp class.
#include "qmeta/xmp.h"
#include <QtCore>
namespace qmeta {
Xmp::Xmp(QObject *parent) : Standard(parent) {}
// Initializes the Xmp object. Returns true if successful.
bool Xmp::Init(QIODevice *file, qint64 file_start_offset) {
set_file(file);
set_file_start_offset(file_start_offset);
// Checks if wrapper exists. Return false if the header is invalid, or if
// the header is valid but the valid trailer is not found.
file->seek(file_start_offset);
if (QString(file->read(17)) == "<?xpacket begin=\"" &&
// Checks the Unicode "zero width non-breaking space charater" (U+FEFF)
// used as a byte-order marker.
file->read(3).toHex() == "efbbbf" &&
// Checks the rest part of the wrapper header.
file->read(31) == "\" id=\"W5M0MpCehiHzreSzNTczkc9d\"") {
// Makes sure the closing notation of the wrapper header exists.
// Note that header attributes other than "begin" and "id" are not
// supported currently.
bool header_is_valid = false;
while (!file->atEnd()) {
if (QString(file->read(1)) == "?" && QString(file->read(1)) == ">") {
header_is_valid = true;
break;
}
}
// Returns false if the wrapper header is invalid.
if (!header_is_valid)
return false;
// Found wrapper header, now checks if the wrapper trailer exists.
bool found_trailer = false;
while (!file->atEnd()) {
if (QString(file->read(1)) == "<" && QString(file->read(1)) == "?" &&
QString(file->read(17)) == "xpacket end=\"w\"?>") {
found_trailer = true;
break;
}
}
if (!found_trailer)
return false;
// Found wrapper trailer. Now we can make sure the XMP wrapper is valid.
}
return true;
}
} // namespace qmeta