From f9324b3f2bf64574bf20e37686624b8600c3ecc4 Mon Sep 17 00:00:00 2001 From: Corentin Allemand Date: Wed, 31 Oct 2012 17:18:37 +0100 Subject: [PATCH 1/2] Add with media params --- utils/HtmlOutputDev.cc | 4 +++- utils/pdftohtml.cc | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index e4bd0b1..7d60975 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -97,6 +97,7 @@ extern GBool stout; extern GBool xml; extern GBool showHidden; extern GBool noMerge; +extern GBool withMedia; extern double wordBreakThreshold; @@ -877,7 +878,8 @@ void HtmlPage::dumpComplex(FILE *file, int page){ fprintf(pageFile,"
\n", page, pageWidth, pageHeight); - if( !ignore ) + + if( !ignore && !withMedia) { fprintf(pageFile, "\"background\n", diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 97372be..72e784f 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -84,6 +84,7 @@ double wordBreakThreshold=10; // 10%, below converted into a coefficient - 0.1 GBool showHidden = gFalse; GBool noMerge = gFalse; GBool fontFullName = gFalse; +GBool withMedia = gFalse; static char ownerPassword[33] = ""; static char userPassword[33] = ""; static GBool printVersion = gFalse; @@ -141,7 +142,9 @@ static const ArgDesc argDesc[] = { {"-wbt", argFP, &wordBreakThreshold, 0, "word break threshold (default 10 percent)"}, {"-fontfullname", argFlag, &fontFullName, 0, - "outputs font full name"}, + "outputs font full name"}, + {"-withmedia", argFlag, &withMedia, 0, + "extract all media"}, {NULL} }; @@ -383,7 +386,7 @@ int main(int argc, char *argv[]) { htmlOut->dumpDocOutline(doc); } - if ((complexMode || singleHtml) && !xml && !ignore) { + if ((complexMode || singleHtml) && !xml && !ignore && !withMedia) { #ifdef HAVE_SPLASH GooString *imgFileName = NULL; // White paper color -- 1.7.10.2 (Apple Git-33) From f2bbe496201746dd107e6147e5577e83a0c7ee75 Mon Sep 17 00:00:00 2001 From: Corentin Allemand Date: Mon, 5 Nov 2012 13:54:50 +0100 Subject: [PATCH 2/2] Extract Video and Sound from AnnotRichMedia --- poppler/Annot.cc | 279 ++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Annot.h | 110 ++++++++++++++++++- poppler/FileSpec.cc | 8 +- poppler/Sound.cc | 14 +-- utils/HtmlOutputDev.cc | 184 ++++++++++++++++++++++++++++++- utils/HtmlOutputDev.h | 64 +++++++++++ 6 files changed, 642 insertions(+), 17 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index dae0f62..a9807ac 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -6494,6 +6494,283 @@ Annot3D::Activation::Activation(Dict *dict) { } //------------------------------------------------------------------------ +// AnnotRichMedia +//------------------------------------------------------------------------ +AnnotRichMediaInstance::AnnotRichMediaInstance(Dict *dict){ + subtype = richMediaSubTypeUnknown; + Object obj1; + //Type name (Optional; ExtensionLevel 3) + if(dict->lookup("Type", &obj1)->isName()){ + type = obj1.getName(); + } + obj1.free(); + //Subtype name (Optional; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + char *stype = obj1.getName(); + if(strcmp(stype, "3D") == 0){ + subtype = richMediaSubType3D; + }else if(strcmp(stype, "Flash") == 0){ + subtype = richMediaSubTypeFlash; + }else if(strcmp(stype, "Sound") == 0){ + subtype = richMediaSubTypeSound; + }else if(strcmp(stype, "Video") == 0){ + subtype = richMediaSubTypeVideo; + } + } + obj1.free(); + //Params dictionary (Optional; ExtensionLevel 3) This entry is valid only for subtype Flash. + if(dict->lookup("Params", &obj1)->isDict()){ + //TODO + } + obj1.free(); + //Asset dictionary (Optional; ExtensionLevel 3) + if(dict->lookup("Asset", &obj1)->isDict()){ + fileSpec = new FileSpec(&obj1); + } + obj1.free(); +} + +AnnotRichMediaInstance::~AnnotRichMediaInstance(){ +} + + + +AnnotRichMediaConfiguration::AnnotRichMediaConfiguration(Dict *dict){ + instances = new GooList(); + subtype = richMediaSubTypeUnknown; + Object obj1; + Object obj2; + //Type name (Optional; ExtensionLevel 3) + if(dict->lookup("Type", &obj1)->isName()){ + type = obj1.getName(); + } + obj1.free(); + //Subtype name (Optional; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + char *stype = obj1.getName(); + if(strcmp(stype, "3D") == 0){ + subtype = richMediaSubType3D; + }else if(strcmp(stype, "Flash") == 0){ + subtype = richMediaSubTypeFlash; + }else if(strcmp(stype, "Sound") == 0){ + subtype = richMediaSubTypeSound; + }else if(strcmp(stype, "Video") == 0){ + subtype = richMediaSubTypeVideo; + } + } + obj1.free(); + //Name text tree (Optional; ExtensionLevel 3) + if(dict->lookup("Name", &obj1)->isName()){ + name = obj1.getName(); + } + obj1.free(); + //Instances array (Optional; ExtensionLevel 3) + if(dict->lookup("Instances", &obj1)->isArray()){ + Array* insts = obj1.getArray(); + AnnotRichMediaInstance *instance; + for (int i = 0; i < insts->getLength(); ++i) { + if(insts->get(i, &obj2)->isDict()){ + instance = new AnnotRichMediaInstance(obj2.getDict()); + instances->append(instance); + } + obj2.free(); + } + } +} + +AnnotRichMediaConfiguration::~AnnotRichMediaConfiguration() { + +} + +AnnotRichMediaContent::AnnotRichMediaContent(Dict *dict){ + Object obj1; + Object obj2; + Object obj3; + configurations = new GooList(); + assets = new GooList(); + //Type name (Optional; ExtensionLevel 3) + if (dict->lookup("Type", &obj1)->isName()) { + type = obj1.getName(); + } + obj1.free(); + + //Assets name tree (Optional; ExtensionLevel 3) + if (dict->lookup("Assets", &obj1)) { + Dict* asts = obj1.getDict(); + if(asts->lookup("Names", &obj2)->isArray()){ + Array* names = obj2.getArray(); + for (int iName = 0; iName < names->getLength(); iName = iName+2) { + if(names->get(iName, &obj3)->isString()){ + //TODO + } + obj3.free(); + if (names->get(iName + 1, &obj3)->isDict()) { + FileSpec* fSpec = new FileSpec(&obj3); + assets->append(fSpec); + } + obj3.free(); + } + } + obj2.free(); + } + obj1.free(); + + //Configurations array (Optional; ExtensionLevel 3) + if (dict->lookup("Configurations", &obj1)->isArray()) { + //Type name (Optional; ExtensionLevel 3) + Array* conf = obj1.getArray(); + AnnotRichMediaConfiguration* configuration; + for (int i = 0; i < conf->getLength(); ++i) { + if(conf->get(0, &obj2)->isDict()){ + configuration = new AnnotRichMediaConfiguration(obj2.getDict()); + configurations->append(configuration); + }else{ + //TODO error; + } + obj2.free(); + } + } + obj1.free(); + //Views array (Optional; ExtensionLevel 3) +} + +AnnotRichMediaContent::~AnnotRichMediaContent() { + if(configurations != NULL){ + delete configurations; + configurations = NULL; + } +} + +AnnotRichMediaActivation::AnnotRichMediaActivation(Dict *dict){ + Object obj1; + //Type name (Optional; ExtensionLevel 3) + if (dict->lookup("Type", &obj1)->isName()) { + type = obj1.getName(); + } + obj1.free(); + //Condition name (Optional; ExtensionLevel 3) + if (dict->lookup("Condition", &obj1)->isName()) { + condition = obj1.getName(); + } + obj1.free(); + //Animation dictionary (Optional; ExtensionLevel 3) + + //View dictionary (Optional; ExtensionLevel 3) + + //Configuration dictionary (Optional; ExtensionLevel 3) + + //Presentation dictionary (Optional; ExtensionLevel 3) + + //Scripts array (Optional; ExtensionLevel 3) + +} + +AnnotRichMediaActivation::~AnnotRichMediaActivation() { + +} + +AnnotRichMediaDeactivation::AnnotRichMediaDeactivation(Dict *dict){ + Object obj1; + //Type name (Optional; ExtensionLevel 3) + if (dict->lookup("Type", &obj1)->isName()) { + type = obj1.getName(); + } + obj1.free(); + //Condition name (Optional; ExtensionLevel 3) + if (dict->lookup("Condition", &obj1)->isName()) { + condition = obj1.getName(); + } + obj1.free(); +} + +AnnotRichMediaDeactivation::~AnnotRichMediaDeactivation() { + +} + +AnnotRichMediaSettings::AnnotRichMediaSettings(Dict *dict){ + Object obj1; + //Type name (Optional; ExtensionLevel 3) + if (dict->lookup("Type", &obj1)->isName()) { + type = obj1.getName(); + } + obj1.free(); + //Activation dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("Activation", &obj1)->isDict()) { + activation = new AnnotRichMediaActivation(obj1.getDict()); + } + obj1.free(); + //Deactivation dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("Deactivation", &obj1)->isDict()) { + deactivation = new AnnotRichMediaDeactivation(obj1.getDict()); + } + obj1.free(); +} + +AnnotRichMediaSettings::~AnnotRichMediaSettings() { + if(activation != NULL){ + delete activation; + activation = NULL; + } + if(deactivation != NULL){ + delete deactivation; + deactivation = NULL; + } +} + + +AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj) : + Annot(docA, dict, obj) { + type = typeRichMedia; + initialize(docA, dict); +} + +AnnotRichMedia::~AnnotRichMedia() { + if(settings != NULL){ + delete settings; + settings = NULL; + } + if(content != NULL){ + delete content; + content = NULL; + } +} + +void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) { + Object obj1; + + //Subtype name (Required; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + char* subtype = obj1.getName(); + }else{ + error(errSyntaxError, -1, "Bad Annot RichMedia"); + //ok = gFalse; + } + obj1.free(); + + //RichMediaSettings dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("RichMediaSettings", &obj1)->isDict()) { + settings = new AnnotRichMediaSettings(obj1.getDict()); + } + obj1.free(); + + //RichMediaContent dictionary (Required; ExtensionLevel 3) + if (dict->lookup("RichMediaContent", &obj1)->isDict()) { + content = new AnnotRichMediaContent(obj1.getDict()); + } + obj1.free(); +} + +void AnnotRichMedia::draw(Gfx *gfx, GBool printing) {} + +GooList* AnnotRichMedia::getConfigurations(){ + GooList* configurations = new GooList(); + if(content != NULL){ + configurations->append(content->getConfigurations()); + } + return configurations; +} + +//------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ @@ -6639,6 +6916,8 @@ Annot *Annots::createAnnot(Dict* dict, Object *obj) { annot = NULL; obj2.free(); + } else if (!strcmp(typeName, "RichMedia")) { + annot = new AnnotRichMedia(doc, dict, obj); } else { annot = new Annot(doc, dict, obj); } diff --git a/poppler/Annot.h b/poppler/Annot.h index 68ddeb7..7435fc4 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -54,6 +54,8 @@ class PDFRectangle; class Movie; class LinkAction; class Sound; +class GooList; +class FileSpec; enum AnnotLineEndingStyle { annotLineEndingSquare, // Square @@ -73,6 +75,11 @@ enum AnnotExternalDataType { annotExternalDataMarkup3D // Markup3D }; +enum AnnotRichMediaSubType { + subTypeMovie, // 0 + subTypeSound // 1 +}; + //------------------------------------------------------------------------ // AnnotCoord //------------------------------------------------------------------------ @@ -516,7 +523,8 @@ public: typePrinterMark, // PrinterMark 22 typeTrapNet, // TrapNet 23 typeWatermark, // Watermark 24 - type3D // 3D 25 + type3D, // 3D 25 + typeRichMedia // RichMedia 26 }; /** @@ -1383,6 +1391,106 @@ private: }; //------------------------------------------------------------------------ +// AnnotRichMedia +//------------------------------------------------------------------------ + +class AnnotRichMediaInstance { +public: + AnnotRichMediaInstance(Dict *dict); + ~AnnotRichMediaInstance(); + int getSubType(){ return subtype; } + +private: + char* type; + int subtype; + char* name; + FileSpec *fileSpec; +}; + +enum RichMediaSubType { + richMediaSubTypeUnknown, + richMediaSubType3D, + richMediaSubTypeFlash, + richMediaSubTypeSound, + richMediaSubTypeVideo +}; +class AnnotRichMediaConfiguration { +public: + AnnotRichMediaConfiguration(Dict *dict); + ~AnnotRichMediaConfiguration(); + int getSubType(){ return subtype; } + GooList* getInstances(){ return instances; } + +private: + char* type; + int subtype; + char* name; + GooList* instances; + +}; + +class AnnotRichMediaContent { +public: + AnnotRichMediaContent(Dict *dict); + ~AnnotRichMediaContent(); + GooList* getConfigurations(){ return configurations; } + GooList* getAssets(){ return assets; } + +private: + char* type; + GooList* configurations; + GooList *assets; +}; + +class AnnotRichMediaActivation { +public: + AnnotRichMediaActivation(Dict *dict); + ~AnnotRichMediaActivation(); + +private: + char* type; + char* condition; +}; + +class AnnotRichMediaDeactivation { +public: + AnnotRichMediaDeactivation(Dict *dict); + ~AnnotRichMediaDeactivation(); + +private: + char* type; + char* condition; +}; + +class AnnotRichMediaSettings { +public: + AnnotRichMediaSettings(Dict *dict); + ~AnnotRichMediaSettings(); + +private: + char* type; + AnnotRichMediaActivation* activation; + AnnotRichMediaDeactivation *deactivation; +}; + +class AnnotRichMedia: public Annot { +public: + AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj); + ~AnnotRichMedia(); + virtual void draw(Gfx *gfx, GBool printing); + GooList* getConfigurations(); + AnnotRichMediaContent* getContent(){ return content; } + +private: + void initialize(PDFDoc *docA, Dict *dict); + int subtype; + AnnotRichMediaContent* content; + AnnotRichMediaSettings* settings; +}; + + + +//------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc index 1adcf5b..9cb459a 100644 --- a/poppler/FileSpec.cc +++ b/poppler/FileSpec.cc @@ -187,12 +187,12 @@ GBool getFileSpecName (Object *fileSpec, Object *fileName) } if (fileSpec->isDict()) { - fileSpec->dictLookup("UF", fileName); + fileSpec->dictLookup("F", fileName); if (fileName->isString()) { return gTrue; } fileName->free(); - fileSpec->dictLookup("F", fileName); + fileSpec->dictLookup("UF", fileName); if (fileName->isString()) { return gTrue; } @@ -224,9 +224,9 @@ GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName) } if (fileSpec->isDict()) { - if (!fileSpec->dictLookup("UF", fileName)->isString ()) { + if (!fileSpec->dictLookup("F", fileName)->isString ()) { fileName->free(); - if (!fileSpec->dictLookup("F", fileName)->isString ()) { + if (!fileSpec->dictLookup("UF", fileName)->isString ()) { fileName->free(); #ifdef _WIN32 char *platform = "DOS"; diff --git a/poppler/Sound.cc b/poppler/Sound.cc index 6129fdc..5f4628c 100644 --- a/poppler/Sound.cc +++ b/poppler/Sound.cc @@ -66,13 +66,13 @@ Sound::Sound(Object *obj, bool readAttrs) Dict *dict = streamObj->getStream()->getDict(); dict->lookup("F", &tmp); if (!tmp.isNull()) { - Object obj1; - // valid 'F' key -> external file - kind = soundExternal; - if (getFileSpecNameForPlatform (&tmp, &obj1)) { - fileName = obj1.getString()->copy(); - obj1.free(); - } + Object obj1; + // valid 'F' key -> external file + kind = soundExternal; + if (getFileSpecNameForPlatform (&tmp, &obj1)) { + fileName = obj1.getString()->copy(); + obj1.free(); + } } else { // no file specification, then the sound data have to be // extracted from the stream diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 7d60975..8052a02 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -66,13 +66,14 @@ #include "HtmlUtils.h" #include "Outline.h" #include "PDFDoc.h" +#include "FileSpec.h" #define DEBUG __FILE__ << ": " << __LINE__ << ": DEBUG: " class HtmlImage { public: - HtmlImage(GooString *_fName, GfxState *state) + HtmlImage(GooString *_fName, GfxState *state) : fName(_fName) { state->transform(0, 0, &xMin, &yMax); state->transform(1, 1, &xMax, &yMin); @@ -105,7 +106,6 @@ static GBool debug = gFalse; static GooString *gstr_buff0 = NULL; // a workspace in which I format strings static GooString* basename(GooString* str){ - char *p=str->getCString(); int len=str->getLength(); for (int i=len-1;i>=0;i--) @@ -114,6 +114,15 @@ static GooString* basename(GooString* str){ return new GooString(str); } +static const char* extension(GooString* str) { + char *p=str->getCString(); + char *dot = strrchr(p, '.'); + if(!dot || dot == p) + return ""; + return dot+1; +} + + #if 0 static GooString* Dirname(GooString* str){ @@ -273,6 +282,8 @@ HtmlPage::HtmlPage(GBool rawOrder, char *imgExtVal) { fonts=new HtmlFontAccu(); links=new HtmlLinks(); imgList=new GooList(); + movieList = new GooList(); + soundList = new GooList(); pageWidth=0; pageHeight=0; fontsPageMarker = 0; @@ -288,6 +299,8 @@ HtmlPage::~HtmlPage() { delete links; delete imgExt; deleteGooList(imgList, HtmlImage); + deleteGooList(movieList, HtmlMovie); + deleteGooList(soundList, HtmlSound); } void HtmlPage::updateFont(GfxState *state) { @@ -886,8 +899,50 @@ void HtmlPage::dumpComplex(FILE *file, int page){ pageWidth, pageHeight, tmp->getCString(), (page-firstPage+1), imgExt->getCString()); } - delete tmp; + + if(!ignore && withMedia){ + int listlen=movieList->getLength(); + GooString *moviefname; + for (int i = 0; i < listlen; i++) { + HtmlMovie *movie = (HtmlMovie*)movieList->del(0); + moviefname=basename(movie->fName); + fprintf(pageFile, + "
", + xoutRound(movie->yMin), + xoutRound(movie->xMin), + xoutRound(movie->xMax-movie->xMin), + xoutRound(movie->yMax-movie->yMin)); + + fprintf(pageFile,"\n", pageFile); + fputs("
\n", pageFile); + delete movie; + } + } + + if(!ignore && withMedia){ + int listlen=soundList->getLength(); + GooString *soundfname; + for (int i = 0; i < listlen; i++) { + HtmlSound *sound = (HtmlSound*)soundList->del(0); + soundfname=basename(sound->fName); + fprintf(pageFile, + "
", + xoutRound(sound->yMin), + xoutRound(sound->xMin), + xoutRound(sound->xMax-sound->xMin), + xoutRound(sound->yMax-sound->yMin)); + + fprintf(pageFile,"\n", pageFile); + fputs("
\n", pageFile); + delete sound; + } + } + for(HtmlString *tmp1=yxStrings;tmp1;tmp1=tmp1->yxNext){ if (tmp1->htext){ @@ -1275,6 +1330,33 @@ void HtmlOutputDev::endPage() { doProcessLink(linksList->getLink(i)); } delete linksList; + Annots *annotsList = docPage->getAnnots(); + for (int i = 0; i < annotsList->getNumAnnots(); ++i) { + Annot *annot = annotsList->getAnnot(i); + + + if(dynamic_cast(annot) != NULL){ + //fprintf(stderr, "IS MOVIE.\n"); + }else if(dynamic_cast(annot) != NULL){ + doProcessRichMedia(dynamic_cast(annot)); + }else if(dynamic_cast(annot) != NULL){ + + } + } + + /* + Movies *moviesList = docPage->getMovies(); + for (int i = 0; i < moviesList->getNumMovies(); ++i) { + doProcessMovie(moviesList->getMovie(i)); + } + delete moviesList; + + RichMedias *richMediasList = docPage->getRichMedias(); + for (int i = 0; i < richMediasList->getNumRichMedias(); ++i) { + doProcessRichMedia(richMediasList->getRichMedia(i)); + } + delete richMediasList; + */ pages->conv(); pages->coalesce(); @@ -1510,8 +1592,6 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, } } - - void HtmlOutputDev::doProcessLink(AnnotLink* link){ double _x1,_y1,_x2,_y2; int x1,y1,x2,y2; @@ -1840,6 +1920,100 @@ void HtmlOutputDev::newXmlOutlineLevel(FILE *output, GooList *outlines, Catalog* #endif } +GooString *HtmlOutputDev::createMovieFileName(const char *ext) +{ + GooString *fName=new GooString(Docname); + fName->append("-"); + GooString *pgNum= GooString::fromInt(pageNum); + GooString *imgnum= GooString::fromInt(pages->getNumMovies()+1);//TODO + + fName->append(pgNum)->append("_")->append(imgnum)->append(".")->append(ext); + delete pgNum; + delete imgnum; + + return fName; +} + +GooString *HtmlOutputDev::createSoundFileName(const char *ext) +{ + GooString *fName=new GooString(Docname); + fName->append("-"); + GooString *pgNum= GooString::fromInt(pageNum); + GooString *imgnum= GooString::fromInt(pages->getNumSounds()+1);//TODO + + fName->append(pgNum)->append("_")->append(imgnum)->append(".")->append(ext); + delete pgNum; + delete imgnum; + + return fName; +} + + +void HtmlOutputDev::doProcessRichMedia(AnnotRichMedia* richMedia){ + double _x1,_y1,_x2,_y2; + int x1,y1,x2,y2; + + richMedia->getRect(&_x1,&_y1,&_x2,&_y2); + cvtUserToDev(_x1,_y1,&x1,&y1); + + cvtUserToDev(_x2,_y2,&x2,&y2); + + GooString *fName; + AnnotRichMediaContent* content = richMedia->getContent(); + GooList *assets = content->getAssets(); + + FileSpec* fileSpec = NULL; + AnnotRichMediaConfiguration* configuration = NULL; + + HtmlMovie* movie; + HtmlSound* sound; + + if(assets->getLength() > 0){ + fileSpec = (FileSpec*) assets->get(0); + } + + GooList *configurations = richMedia->getConfigurations(); + if(configurations->getLength() > 0){ + configuration = (AnnotRichMediaConfiguration*) configurations->get(0); + } + + if(fileSpec != NULL && configuration != NULL){ + if(configuration->getSubType() == richMediaSubTypeVideo){ + fName = createMovieFileName(extension(fileSpec->getFileNameForPlatform())); + fileSpec->getEmbeddedFile()->save(fName->getCString()); + movie = new HtmlMovie((double) x1, (double) y2, (double) x2, (double) y1, fName); + pages->addMovie(movie); + }else if(configuration->getSubType() == richMediaSubTypeSound){ + fName = createSoundFileName(extension(fileSpec->getFileNameForPlatform())); + fileSpec->getEmbeddedFile()->save(fName->getCString()); + sound = new HtmlSound((double) x1, (double) y2, (double) x2, (double) y1, fName); + pages->addSound(sound); + } + } + + +} + +void HtmlOutputDev::doWriteStream(Stream* str, GooString* fileName){ + if(str != NULL && fileName != NULL){ + FILE *f1; + int c; + if (!(f1 = fopen(fileName->getCString(), "wb"))) { + error(errIO, -1, "Couldn't open file '%s'", fileName->getCString()); + return; + } + + // initialize stream + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f1); + fclose(f1); + } +} + + #ifndef DISABLE_OUTLINE int HtmlOutputDev::getOutlinePageNum(OutlineItem *item) { diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h index 12b16bf..cac2f7e 100644 --- a/utils/HtmlOutputDev.h +++ b/utils/HtmlOutputDev.h @@ -62,6 +62,48 @@ class GfxState; class GooString; class PDFDoc; class OutlineItem; + + +//------------------------------------------------------------------------ +// HtmlMovie +//------------------------------------------------------------------------ +class HtmlMovie +{ +public: + HtmlMovie(double x1, double y1, double x2, double y2, GooString* _fName){ + xMin = x1; + yMin = y1; + xMax = x2; + yMax = y2; + fName = _fName; + } + ~HtmlMovie() { delete fName; } + + double xMin, xMax; // image x coordinates + double yMin, yMax; // image y coordinates + GooString *fName; // image file name +}; + +//------------------------------------------------------------------------ +// HtmlSound +//------------------------------------------------------------------------ +class HtmlSound +{ +public: + HtmlSound(double x1, double y1, double x2, double y2, GooString* _fName){ + xMin = x1; + yMin = y1; + xMax = x2; + yMax = y2; + fName = _fName; + } + ~HtmlSound() { delete fName; } + + double xMin, xMax; // image x coordinates + double yMin, yMax; // image y coordinates + GooString *fName; // image file name +}; + //------------------------------------------------------------------------ // HtmlString //------------------------------------------------------------------------ @@ -160,9 +202,24 @@ public: // add an image to the current page void addImage(GooString *fname, GfxState *state); + // add an movie to the current page + void addMovie(HtmlMovie *movie){ + movieList->append(movie); + } + // add an sound to the current page + void addSound(HtmlSound *sound){ + soundList->append(sound); + } + // number of images on the current page int getNumImages() { return imgList->getLength(); } + // number of movies on the current page + int getNumMovies() { return movieList->getLength(); } + + // number of sounds on the current page + int getNumSounds() { return soundList->getLength(); } + void dump(FILE *f, int pageNum); // Clear the page. @@ -186,11 +243,14 @@ private: void dumpComplex(FILE* f, int page); int dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page); + // marks the position of the fonts that belong to current page (for noframes) int fontsPageMarker; HtmlFontAccu *fonts; HtmlLinks *links; GooList *imgList; + GooList *movieList; + GooList *soundList; GooString *DocName; GooString *imgExt; @@ -329,6 +389,10 @@ private: void drawPngImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool isMask = gFalse); GooString *createImageFileName(const char *ext); + GooString *createMovieFileName(const char *ext); + GooString *createSoundFileName(const char *ext); + void doProcessRichMedia(AnnotRichMedia* richMedia); + void doWriteStream(Stream* str, GooString* fileName); FILE *fContentsFrame; FILE *page; // html file -- 1.7.10.2 (Apple Git-33)