#1074. Implemented exiv2 options -eC and -pC for JPEG.

This commit is contained in:
Robin Mills 2015-08-26 15:05:58 +00:00
parent ccb462869f
commit 6808b073f3
8 changed files with 75 additions and 11 deletions

View File

@ -74,7 +74,7 @@ namespace Exiv2 {
/*!
@brief Options for printStructure
*/
typedef enum { kpsNone, kpsBasic, kpsXMP } PrintStructureOption;
typedef enum { kpsNone, kpsBasic, kpsXMP, kpsRecursive, kpsIccProfile } PrintStructureOption;
/*!
@brief Abstract base class defining the interface for an image. This is

View File

@ -241,8 +241,10 @@ namespace Action {
case Params::pmList: rc = printList(); break;
case Params::pmComment: rc = printComment(); break;
case Params::pmPreview: rc = printPreviewList(); break;
case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic); break;
case Params::pmXMP: rc = printStructure(std::cout,Exiv2::kpsXMP); break;
case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic) ; break;
case Params::pmXMP: rc = printStructure(std::cout,Exiv2::kpsXMP) ; break;
case Params::pmIccProfile:rc = printStructure(std::cout,Exiv2::kpsIccProfile); break;
case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive) ; break;
}
return rc;
}
@ -1007,6 +1009,9 @@ namespace Action {
if (Params::instance().target_ & Params::ctPreview) {
rc = writePreviews();
}
if (Params::instance().target_ & Params::ctIccProfile) {
rc = writeIccProfile();
}
if ( !(Params::instance().target_ & Params::ctXmpSidecar)
&& !(Params::instance().target_ & Params::ctThumb)
&& !(Params::instance().target_ & Params::ctPreview)) {
@ -1098,6 +1103,32 @@ namespace Action {
return 0;
} // Extract::writePreviews
int Extract::writeIccProfile() const
{
if (!Exiv2::fileExists(path_, true)) {
std::cerr << path_
<< ": " << _("Failed to open the file\n");
return -1;
}
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_);
assert(image.get() != 0);
image->readMetadata();
std::string iccPath = newFilePath(path_,".icc");
std::filebuf iccBuffer ;
iccBuffer.open(iccPath,std::ios::out);
std::ostream iccStream(&iccBuffer);
image->printStructure(iccStream,Exiv2::kpsIccProfile);
iccBuffer.close();
if (Params::instance().verbose_) {
std::cout << _("Writing iccProfile: ") << iccPath << std::endl;
}
return 0;
} // Extract::writeIccProfile
void Extract::writePreviewFile(const Exiv2::PreviewImage& pvImg, int num) const
{
std::string pvFile = newFilePath(path_, "-preview") + Exiv2::toString(num);

View File

@ -309,6 +309,10 @@ namespace Action {
depending on the format of the Exif thumbnail image.
*/
void writePreviewFile(const Exiv2::PreviewImage& pvImg, int num) const;
/*!
@brief Write embedded iccProfile files.
*/
int writeIccProfile() const;
private:
virtual Extract* clone_() const;

View File

@ -369,6 +369,7 @@ int Params::option(int opt, const std::string& optarg, int optopt)
case 'P': rc = evalPrintFlags(optarg); break;
case 'd': rc = evalDelete(optarg); break;
case 'e': rc = evalExtract(optarg); break;
case 'C': rc = evalExtract(optarg); break;
case 'i': rc = evalInsert(optarg); break;
case 'c': rc = evalModify(opt, optarg); break;
case 'm': rc = evalModify(opt, optarg); break;
@ -560,10 +561,12 @@ int Params::evalPrint(const std::string& optarg)
case 'h': rc = evalPrintFlags("Exgnycsh"); break;
case 'i': rc = evalPrintFlags("Ikyct"); break;
case 'x': rc = evalPrintFlags("Xkyct"); break;
case 'c': action_ = Action::print; printMode_ = pmComment ; break;
case 'p': action_ = Action::print; printMode_ = pmPreview ; break;
case 'S': action_ = Action::print; printMode_ = pmStructure; break;
case 'X': action_ = Action::print; printMode_ = pmXMP ; break;
case 'c': action_ = Action::print; printMode_ = pmComment ; break;
case 'p': action_ = Action::print; printMode_ = pmPreview ; break;
case 'C': action_ = Action::print; printMode_ = pmIccProfile ; break;
case 'R': action_ = Action::print; printMode_ = pmRecursive ; break;
case 'S': action_ = Action::print; printMode_ = pmStructure ; break;
case 'X': action_ = Action::print; printMode_ = pmXMP ; break;
default:
std::cerr << progname() << ": " << _("Unrecognized print mode") << " `"
<< optarg << "'\n";
@ -1017,6 +1020,7 @@ namespace {
case 'x': target |= Params::ctXmp; break;
case 'c': target |= Params::ctComment; break;
case 't': target |= Params::ctThumb; break;
case 'C': target |= Params::ctIccProfile; break;
case 'a': target |= Params::ctExif
| Params::ctIptc
| Params::ctComment

View File

@ -148,7 +148,9 @@ public:
pmComment,
pmPreview,
pmStructure,
pmXMP
pmXMP,
pmIccProfile,
pmRecursive
};
//! Individual items to print, bitmap
@ -174,7 +176,8 @@ public:
ctThumb = 8,
ctXmp = 16,
ctXmpSidecar = 32,
ctPreview = 64
ctPreview = 64,
ctIccProfile =128
};
//! Enumerates the policies to handle existing files in rename action

View File

@ -527,7 +527,7 @@ namespace Exiv2 {
throw Error(15);
}
if ( option == kpsBasic || option == kpsXMP ) {
if ( option == kpsBasic || option == kpsXMP || option == kpsIccProfile || option == kpsRecursive) {
// nmonic for markers
std::string nm[256] ;
@ -565,7 +565,7 @@ namespace Exiv2 {
bool first= true;
while (!done) {
// print marker bytes
if ( first && option == kpsBasic ) {
if ( first && (option == kpsBasic||option==kpsRecursive) ) {
out << "STRUCTURE OF JPEG FILE: " << io_->path() << std::endl;
out << " address | marker | length | data" << std::endl ;
REPORT_MARKER;
@ -597,7 +597,9 @@ namespace Exiv2 {
char http[5];
http[4]=0;
memcpy(http,buf.pData_+2,4);
if ( option == kpsXMP && std::strcmp(http,"http") == 0 ) {
// extract XMP
// http://ns.adobe.com/xap/1.0/
if ( size > 0 ) {
io_->seek(-bufRead , BasicIo::cur);
@ -624,6 +626,17 @@ namespace Exiv2 {
delete [] xmp;
bufRead = size;
}
} else if ( option == kpsIccProfile && std::strcmp(http,"ICC_") == 0 ) {
// extract ICCProfile
if ( size > 0 ) {
io_->seek(-bufRead , BasicIo::cur);
byte* icc = new byte[size];
io_->read(icc,size);
std::size_t start=16;
out.write( ((const char*)icc)+start,size-start);
bufRead = size;
delete [] icc;
}
} else if ( option == kpsBasic ) {
out << "| " << Internal::binaryToString(buf,32,size>0?2:0);
}

View File

@ -104,6 +104,10 @@ namespace Exiv2 {
throw Error(3, "PNG");
}
if ( option == kpsIccProfile || option == kpsRecursive ) {
throw Error(13, io_->path());
}
char chType[5];
chType[0]=0;
chType[4]=0;

View File

@ -455,6 +455,11 @@ namespace Exiv2 {
throw Error(15);
}
if ( option == kpsIccProfile || option == kpsRecursive ) {
throw Error(13, io_->path());
}
if ( option == kpsBasic || option == kpsXMP ) {
io_->seek(0,BasicIo::beg);
// buffer