Skip to content

Commit

Permalink
Merge pull request #62 from Kicer86/crash_fix
Browse files Browse the repository at this point in the history
Fix for crash in multithread environment
  • Loading branch information
clanmills committed Sep 2, 2017
2 parents c016c89 + 20582a9 commit 31fc5d2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 36 deletions.
6 changes: 6 additions & 0 deletions include/exiv2/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,18 @@ namespace Exiv2 {
Image& operator=(const Image& rhs);
//@}

//! Return tag name for given tag id.
const std::string& tagName(uint16_t tag);

// DATA
int imageType_; //!< Image type
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
bool writeXmpFromPacket_;//!< Determines the source when writing XMP
ByteOrder byteOrder_; //!< Byte order

std::map<int,std::string> tags_; //!< Map of tags
bool init_; //!< Flag marking if map of tags needs to be initialized

}; // class Image

//! Type for function pointer that creates new Image instances
Expand Down
59 changes: 23 additions & 36 deletions src/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ namespace Exiv2 {
#else
writeXmpFromPacket_(true),
#endif
byteOrder_(invalidByteOrder)
byteOrder_(invalidByteOrder),
tags_(),
init_(true)
{
}

Expand Down Expand Up @@ -273,40 +275,6 @@ namespace Exiv2 {
return Image::byteSwap(v,bSwap);
}

static const char* tagName(uint16_t tag,size_t nMaxLength)
{
const char* result = NULL;

// build a static map of tags for fast search
static std::map<int,std::string> tags;
static bool init = true;
static char buffer[80];

if ( init ) {
int idx;
const TagInfo* ti ;
for (ti = Internal:: mnTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: iopTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: gpsTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: ifdTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal::exifTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: mpfTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal::Nikon1MakerNote::tagList(), idx = 0
; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
}
init = false;

try {
result = tags[tag].c_str();
if ( nMaxLength > sizeof(buffer) -2 )
nMaxLength = sizeof(buffer) -2;
strncpy(buffer,result,nMaxLength);
result = buffer;
} catch ( ... ) {}

return result ;
}

static const char* typeName(uint16_t tag)
{
//! List of TIFF image tags
Expand Down Expand Up @@ -413,7 +381,7 @@ namespace Exiv2 {
uint32_t address = start + 2 + i*12 ;
out << Internal::indent(depth)
<< Internal::stringFormat("%8u | %#06x %-25s |%10s |%9u |%10u | "
,address,tag,tagName(tag,25),typeName(type),count,offset);
,address,tag,tagName(tag).c_str(),typeName(type),count,offset);
if ( isShortType(type) ){
for ( size_t k = 0 ; k < kount ; k++ ) {
out << sp << byteSwap2(buf,k*size,bSwap);
Expand Down Expand Up @@ -727,6 +695,25 @@ namespace Exiv2 {
return ImageFactory::checkMode(imageType_, metadataId);
}

const std::string& Image::tagName(uint16_t tag)
{
if ( init_ ) {
int idx;
const TagInfo* ti ;
for (ti = Internal:: mnTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: iopTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: gpsTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: ifdTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal::exifTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal:: mpfTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
for (ti = Internal::Nikon1MakerNote::tagList(), idx = 0
; ti[idx].tag_ != 0xffff; ++idx) tags_[ti[idx].tag_] = ti[idx].name_;
}
init_ = false;

return tags_[tag] ;
}

AccessMode ImageFactory::checkMode(int type, MetadataId metadataId)
{
const Registry* r = find(registry, type);
Expand Down

0 comments on commit 31fc5d2

Please sign in to comment.