void StTranslations::setLanguage(const int32_t theNewLang) { if(size_t(theNewLang) >= params.language->getValues().size()) { return; } // save global setting const StString& aFolderName = myLangFolderList[theNewLang]; StSettings aGlobalSettings(myResMgr, ST_GLOBAL_SETTINGS_GROUP); aGlobalSettings.saveString(ST_SETTING_LANGUAGE, aFolderName); updateLangCode(theNewLang); // reload translation file StLangMap::clear(); const StString aResName = StString() + "lang" ST_FILE_SPLITTER + aFolderName + SYS_FS_SPLITTER + myModuleName + StTranslations::DEFAULT_SUFFIX; StHandle<StResource> aRes = myResMgr->getResource(aResName); if(!aRes.isNull() && aRes->read()) { const char* aSrc = (const char* )aRes->getData(); const int aLen = aRes->getSize(); read(aSrc, aLen); } myWasReloaded = true; }
void StApplication::addAction(const int theActionId, StHandle<StAction>& theAction, const unsigned int theHotKey1, const unsigned int theHotKey2) { theAction->setDefaultHotKey1(theHotKey1); theAction->setDefaultHotKey2(theHotKey2); addAction(theActionId, theAction); }
void StImageFileCounter::createReference(StHandle<StBufferCounter>& theOther) const { StHandle<StImageFileCounter> anImgFileRef = StHandle<StImageFileCounter>::downcast(theOther); if(anImgFileRef.isNull()) { anImgFileRef = new StImageFileCounter(); theOther = anImgFileRef; } anImgFileRef->myImageFile = myImageFile; }
void StTestEmbed::embedAppLoop() { StHandle<StApplication> anApp = new StApplication(new StResourceManager(), myParent); if(!anApp->open()) { return; } anApp->exec(); }
void StActiveXCtrl::stWindowLoop() { // do not load plugin until it is placed on screen StWindow aParentWin(myResMgr, myParentWin); for(;;) { if(aParentWin.isParentOnScreen()) { break; } StThread::sleep(10); if(myToQuit) { return; } } myStApp = new StImageViewer(myResMgr, myParentWin, new StOpenInfo()); if(!myStApp->open()) { myStApp.nullify(); return; } bool isFullscreen = false; myIsActive = true; for(;;) { if(myStApp->closingDown()) { myStApp.nullify(); myIsActive = false; return; } myIsActive = myStApp->isActive(); if(myToQuit) { myStApp->exit(0); } else if(myOpenEvent.check() && myStApp->isActive()) { // load the image myStApp->open(myOpenInfo); myOpenEvent.reset(); } StHandle<StWindow> aWin = myStApp->getMainWindow(); if(myIsActive) { aWin->show(); } else { aWin->hide(); } myStApp->processEvents(); if(aWin->isFullScreen()) { if(!isFullscreen) { PostMessage(WM_TIMER, 1); isFullscreen = true; } } else if(isFullscreen) { PostMessage(WM_TIMER, 0); isFullscreen = false; } } }
StHandle<StFileNode> StFileNode::detach() const { StHandle<StFileNode> aCopy = new StFileNode(getPath()); aCopy->setMIME(getMIME()); for(size_t aSubId = 0; aSubId < size(); ++aSubId) { const StFileNode* aSubNode = getValue(aSubId); aCopy->add(new StFileNode(aSubNode->getSubPath(), aCopy.access())); } return aCopy; }
void StJpegParser::fillDictionary(StDictionary& theDict, const bool theToShowUnknown) const { for(StHandle<StJpegParser::Image> anImg = myImages; !anImg.isNull(); anImg = anImg->Next) { for(size_t anExifId = 0; anExifId < anImg->Exif.size(); ++anExifId) { anImg->Exif[anExifId]->fillDictionary(theDict, theToShowUnknown); } } }
bool StJpegParser::insertSection(const uint8_t theMarker, const uint16_t theSectLen, const ptrdiff_t theOffset) { const size_t aDiff = size_t(theSectLen) + 2; // 2 bytes for marker const size_t aNewSize = myLength + aDiff; if(aNewSize > myBuffSize) { myBuffSize = aNewSize + 256; stUByte_t* aNewData = stMemAllocAligned<stUByte_t*>(myBuffSize); if(aNewData == NULL) { return false; } stMemCpy(aNewData, myBuffer, myLength); if(myIsOwnData) { stMemFreeAligned(myBuffer); } myIsOwnData = true; // update pointers of image(s) data for(StHandle<StJpegParser::Image> anImg = myImages; !anImg.isNull(); anImg = anImg->Next) { ptrdiff_t anOffset = anImg->Data - myBuffer; if(anOffset >= theOffset) { anOffset += aDiff; } anImg->Data = aNewData + anOffset; if(!anImg->Thumb.isNull()) { anOffset = anImg->Thumb->Data - myBuffer; if(anOffset >= theOffset) { anOffset += aDiff; } anImg->Thumb->Data = aNewData + anOffset; } } myBuffer = aNewData; } myLength = aNewSize; // update offset table for(size_t anIter = 0; anIter < OffsetsNb; ++anIter) { if(myOffsets[anIter] >= theOffset) { myOffsets[anIter] += aDiff; } } // initialize new section const size_t aTailSize = myLength - theOffset; std::memmove(myBuffer + theOffset + 2 + size_t(theSectLen), myBuffer + theOffset, aTailSize); stUByte_t* aData = myBuffer + theOffset; aData[0] = 0xFF; aData[1] = theMarker; StAlienData::Set16uBE(aData + 2, theSectLen); return true; }
void StApplication::addAction(const int theActionId, const StHandle<StAction>& theAction) { myActions[theActionId] = theAction; if(!theAction.isNull()) { StString aNameLower = theAction->getName(); aNameLower.toLowerCase(); const std::string aName(aNameLower.toCString()); myActionLookup[aName] = theActionId; } }
int main(int , char** ) { // force console output #else int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { // prevent console output #endif setlocale(LC_ALL, ".OCP"); // we set default locale for console output (useful only for debug) #else int main(int , char** ) { #endif StOutPageFlip::initGlobalsAsync(); if(!StVersionInfo::checkTimeBomb("sView")) { return 1; } // setup environment variables const StString ST_ENV_NAME_STCORE_PATH = #if defined(_WIN64) || defined(_LP64) || defined(__LP64__) "StCore64"; #else "StCore32"; #endif const StString aProcessPath = StProcess::getProcessFolder(); StString aProcessUpPath = StFileNode::getFolderUp(aProcessPath); if(!aProcessUpPath.isEmpty()) { aProcessUpPath += SYS_FS_SPLITTER; } StProcess::setEnv(ST_ENV_NAME_STCORE_PATH, aProcessPath); if(StFolder::isFolder(aProcessPath + "textures")) { StProcess::setEnv("StShare", aProcessPath); } else if(StFolder::isFolder(aProcessUpPath + "textures")) { StProcess::setEnv("StShare", aProcessUpPath); } StString aResDir = StProcess::getStShareFolder(); StProcess::setEnv("CSF_UnitsLexicon", aResDir + "UnitsAPI" ST_FILE_SPLITTER "Lexi_Expr.dat"); StProcess::setEnv("CSF_UnitsDefinition", aResDir + "UnitsAPI" ST_FILE_SPLITTER "Units.dat"); StProcess::setEnv("CSF_ShadersDirectory", aResDir + "shaders" ST_FILE_SPLITTER "StCADViewer"); StProcess::setEnv("CSF_SHMessage", aResDir + "lang"); StProcess::setEnv("CSF_MDTVTexturesDirectory", aResDir + "textures"); StHandle<StOpenInfo> anInfo; if(anInfo.isNull() || (!anInfo->hasPath() && !anInfo->hasArgs())) { anInfo = StApplication::parseProcessArguments(); } if(anInfo.isNull()) { // show help StString aShowHelpString = getAbout(); st::cout << aShowHelpString; stInfo(aShowHelpString); return 0; } StHandle<StResourceManager> aResMgr = new StResourceManager(); StHandle<StCADViewer> anApp = new StCADViewer(aResMgr, NULL, anInfo); if(!anApp->open()) { return 1; } return anApp->exec(); }
bool StDXManager::checkAqbsSupport(const HWND theWinHandle) { if(!initDxLib()) { return false; } const UINT aD3dAdaptersNb = getAdapterCount(); D3DADAPTER_IDENTIFIER9 anAdapterInfo; for(UINT anAdapterIter = 0; anAdapterIter < aD3dAdaptersNb; ++anAdapterIter) { getAdapterIdentifier(anAdapterIter, 0, &anAdapterInfo); if(anAdapterInfo.VendorId != ST_DX_VENDOR_AMD) { continue; } // setup the present parameters if(getAdapterDisplayMode(anAdapterIter, &myCurrMode) == D3D_OK) { myD3dParams.BackBufferFormat = myCurrMode.Format; myRefreshRate = myCurrMode.RefreshRate; } // create temporary video device myD3dParams.hDeviceWindow = theWinHandle; myD3dDevice = createAqbsTmpDevice(anAdapterIter, theWinHandle, myD3dParams); if(myD3dDevice == NULL) { continue; } // create a surface to be used to communicate with the driver StHandle<StDXAqbsControl> anAqbsControl = new StDXAqbsControl(myD3dDevice); if(!anAqbsControl->isValid()) { myD3dDevice->Release(); myD3dDevice = NULL; return false; } // send the command to the driver using the temporary surface if(!anAqbsControl->enableStereo()) { anAqbsControl.nullify(); myD3dDevice->Release(); myD3dDevice = NULL; return false; } myWithAqbs = true; anAqbsControl.nullify(); myD3dDevice->Release(); myD3dDevice = NULL; return true; } return false; }
void StApplication::addRenderer(const StHandle<StWindow>& theRenderer) { if(theRenderer.isNull()) { return; } StHandle<StWindow> aRenderer = theRenderer; aRenderer->params.VSyncMode = params.VSyncMode; // share VSync mode between renderers aRenderer->setMessagesQueue(myMsgQueue); myRenderers.add(aRenderer); size_t aDevIter = myDevices.size(); aRenderer->getDevices(myDevices); for(; aDevIter < myDevices.size(); ++aDevIter) { params.ActiveDevice->changeValues().add(myDevices[aDevIter]->Name); } }
ST_LOCAL StGLMenuActionItem(StGLMenu* theParent, const StHandle<StAction>& theAction, StGLMenu* theSubMenu) : StGLMenuItem(theParent, 0, 0, theSubMenu), myAction(theAction) { ST_ASSERT(!theAction.isNull(), "StGLMenuActionItem - Unexpected empty action makes no sense!"); StGLMenuItem::signals.onItemClick.connect(this, &StGLMenuActionItem::doItemClick); }
bool StJpegParser::parse() { if(myBuffer == NULL) { return false; } int aCount = 0; myImages = parseImage(++aCount, 1, myBuffer, false); if(myImages.isNull()) { return false; } // continue reading the file (MPO may contains more than 1 image) for(StHandle<StJpegParser::Image> anImg = myImages; !anImg.isNull(); anImg = anImg->Next) { anImg->Next = parseImage(++aCount, 1, anImg->Data + anImg->Length, true); } return true; }
bool StPlayList::removePhysically(const StHandle<StFileNode>& theFileNode) { StString aPath = theFileNode->getPath(); StPlayItem* aRemItem = NULL; StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL) { // empty playlist return false; } else if(aPath != myCurrent->getPath()) { // search play item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(aPath == anItem->getPath()) { aRemItem = anItem; break; } } } else { // walk to another playlist position aRemItem = myCurrent; const bool aPlayedFlag = aRemItem->getPlayedFlag(); if(myCurrent->hasNext()) { myCurrent = myCurrent->getNext(); } else if(myCurrent->hasPrev()) { myCurrent = myCurrent->getPrev(); } else { myCurrent = NULL; myPlayedCount = 0; } if(myCurrent != NULL) { if(aRemItem->getPlayedFlag() != aPlayedFlag) { // the item has not been played yet - mark it as such aRemItem->setPlayedFlag(aPlayedFlag); } else { // one played item has been removed --myPlayedCount; } } } // remove item itself const bool isDeleted = aRemItem != NULL && StFileNode::removeFile(aPath); if(isDeleted) { delPlayItem(aRemItem); delete aRemItem; } anAutoLock.unlock(); signals.onPlaylistChange(); return isDeleted; }
void StCADViewerGUI::doOpenFile(const size_t ) { StGLOpenFile* aDialog = new StGLOpenFile(this, tr(DIALOG_OPEN_FILE), tr(BUTTON_CLOSE)); aDialog->setMimeList(StCADLoader::ST_CAD_MIME_LIST); #if defined(_WIN32) // #else aDialog->addHotItem("/", "Root"); #endif aDialog->addHotItem(getResourceManager()->getFolder(StResourceManager::FolderId_SdCard)); aDialog->addHotItem(getResourceManager()->getFolder(StResourceManager::FolderId_Downloads)); aDialog->addHotItem(getResourceManager()->getFolder(StResourceManager::FolderId_Pictures)); aDialog->addHotItem(getResourceManager()->getFolder(StResourceManager::FolderId_Photos)); aDialog->signals.onFileSelected = stSlot(myPlugin, &StCADViewer::doOpen1FileFromGui); if(myPlugin->params.LastFolder.isEmpty()) { StHandle<StFileNode> aCurrFile = myPlugin->myPlayList->getCurrentFile(); if(!aCurrFile.isNull()) { myPlugin->params.LastFolder = aCurrFile->isEmpty() ? aCurrFile->getFolderPath() : aCurrFile->getValue(0)->getFolderPath(); } } aDialog->openFolder(myPlugin->params.LastFolder); setModalDialog(aDialog); }
bool StPlayList::getCurrentFile(StHandle<StFileNode>& theFileNode, StHandle<StStereoParams>& theParams, StHandle<StFileNode>& thePlsFile) { theFileNode.nullify(); theParams.nullify(); thePlsFile.nullify(); StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL) { // empty list return false; } StFileNode* aFileNode = myCurrent->getFileNode(); if(aFileNode == NULL) { // invalid item return false; } theFileNode = aFileNode->detach(); theParams = myCurrent->getParams(); if(!myPlsFile.isNull()) { thePlsFile = myPlsFile->File; } return true; }
StTrackedFloatParam(const StHandle<StFloat32Param>& theTracked1, const StHandle<StFloat32Param>& theTracked2) : StFloat32Param(theTracked1->getValue(), theTracked1->getMinValue(), theTracked1->getMaxValue(), theTracked1->getDefValue(), theTracked1->getStep(), theTracked1->getTolerance()), myTracked1(theTracked1), myTracked2(theTracked2) {}
void StPlayList::loadRecentList(const StString theString) { StMutexAuto anAutoLock(myMutex); StArgumentsMap aMap; aMap.parseString(theString); myRecent.clear(); for(size_t anIter = 0; anIter < myRecentLimit; ++anIter) { const StArgument anArgFile = aMap[StString("file") + anIter]; const StArgument anArgLeft = aMap[StString("left") + anIter]; const StArgument anArgRight = aMap[StString("right") + anIter]; const StArgument anArgTime = aMap[StString("time") + anIter]; StHandle<StRecentItem> aRecent; if(anArgLeft.isValid() && anArgRight.isValid()) { StHandle<StFileNode> aFileNode = new StFileNode(StString()); aFileNode->add(new StFileNode(anArgLeft.getValue(), aFileNode.access())); aFileNode->add(new StFileNode(anArgRight.getValue(), aFileNode.access())); aRecent = addRecentFile(*aFileNode, false); } else if(anArgFile.isValid()) { StHandle<StFileNode> aFileNode = new StFileNode(anArgFile.getValue()); const StArgument anArgPos = aMap[StString("pos") + anIter]; if(anArgPos.isValid()) { aFileNode->add(new StFileNode(anArgPos.getValue(), aFileNode.access())); } aRecent = addRecentFile(*aFileNode, false); } if(aRecent.isNull()) { continue; } if(anArgTime.isValid()) { if(aRecent->Params.isNull()) { aRecent->Params = new StStereoParams(); } std::stringstream aStream; aStream.imbue(std::locale("C")); aStream << anArgTime.getValue().toCString(); aStream >> aRecent->Params->Timestamp; } } }
void StPlayList::updateRecent(const StHandle<StFileNode>& theFile, const StHandle<StStereoParams>& theParams) { if(theFile.isNull()) { return; } StMutexAuto anAutoLock(myMutex); if(!myPlsFile.isNull() && myPlsFile->File == theFile) { // remember properties of last played file myPlsFile->Params = theParams; return; } for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { StHandle<StRecentItem>& aRecent = myRecent[anIter]; if(stAreSameRecent(*theFile, *aRecent->File)) { aRecent->Params = theParams; return; } } }
StHandle<StStereoParams> StPlayList::openRecent(const size_t theItemId) { StMutexAuto anAutoLock(myMutex); if(theItemId >= myRecent.size()) { return StHandle<StStereoParams>(); } const StHandle<StRecentItem> aRecent = myRecent[theItemId]; const StHandle<StFileNode> aFile = aRecent->File; if(aFile->size() == 2) { // stereo pair from two files clear(); addOneFile(aFile->getValue(0)->getPath(), aFile->getValue(1)->getPath()); } else if(aFile->size() == 1) { // playlist open(aFile->getPath(), aFile->getValue(0)->getSubPath()); } else { // single file open(aFile->getPath()); } return aRecent->Params; }
void StPlayList::addToNode(const StHandle<StFileNode>& theFileNode, const StString& thePathToAdd) { StString aPath = theFileNode->getPath(); StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL) { return; } else if(aPath != myCurrent->getPath()) { for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(aPath == anItem->getPath()) { myCurrent = anItem; break; } } } StFileNode* aFileNode = myCurrent->getFileNode(); if(aFileNode->getParent() != &myFoldersRoot) { // convert filenode to metafile with empty root aFileNode->reParent(&myFoldersRoot); aFileNode->setSubPath(StString()); aFileNode->add(new StFileNode(aPath, aFileNode)); } aFileNode->add(new StFileNode(thePathToAdd, aFileNode)); }
/** * Copy OCCT resource file. */ ST_LOCAL bool copyResource(const StHandle<StResourceManager>& theResMgr, const StString& theResFolder, const StString& theDestFolder, const StString& theFileName) { StString aFileResPath = theResFolder + SYS_FS_SPLITTER + theFileName; StHandle<StResource> aRes = theResMgr->getResource(aFileResPath); if( aRes.isNull() || !aRes->read()) { ST_ERROR_LOG(StString("Can not read resource file ") + aFileResPath); return false; } StRawFile aFileOut; StString aFileOutPath = theDestFolder + SYS_FS_SPLITTER + theFileName; if(!aFileOut.openFile(StRawFile::WRITE, aFileOutPath)) { ST_ERROR_LOG(StString("Can not create resource file ") + aFileOutPath); return false; } if(!aFileOut.write((const char* )aRes->getData(), aRes->getSize()) != aRes->getSize()) { ST_ERROR_LOG(StString("Can not write resource file ") + aFileOutPath); return false; } return true; }
void StApplication::registerHotKeys() { myKeyActions.clear(); for(std::map< int, StHandle<StAction> >::iterator anIter = myActions.begin(); anIter != myActions.end(); ++anIter) { const StHandle<StAction>& anAction = anIter->second; if(anAction->getHotKey1() != 0) { StHandle<StAction> anOldAction = getActionForKey(anAction->getHotKey1()); if(!anOldAction.isNull()) { anOldAction->setHotKey1(0); } myKeyActions[anAction->getHotKey1()] = anAction; } if(anAction->getHotKey2() != 0) { StHandle<StAction> anOldAction = getActionForKey(anAction->getHotKey2()); if(!anOldAction.isNull()) { anOldAction->setHotKey2(0); } myKeyActions[anAction->getHotKey2()] = anAction; } } }
StHandle<StJpegParser::Image> StJpegParser::parseImage(const int theImgCount, const int theDepth, unsigned char* theDataStart, const bool theToFindSOI) { // check out of bounds if(theDataStart == NULL) { return StHandle<StJpegParser::Image>(); } unsigned char* aData = theDataStart; const unsigned char* aDataEnd = myBuffer + myLength; // search image beginning if(theToFindSOI) { ++aData; for(; aData < aDataEnd; ++aData) { if(aData[-1] == 0xFF && aData[0] == M_SOI) { --aData; break; } } } // check out of bounds if((aData + 2) > aDataEnd) { return StHandle<StJpegParser::Image>(); } // check the jpeg identifier if(aData[0] != 0xFF || aData[1] != M_SOI) { ST_DEBUG_LOG("StJpegParser, no SOI at position " + size_t(aData - myBuffer) + " / " + myLength); return StHandle<StJpegParser::Image>(); } aData += 2; // skip already read bytes // parse the data StHandle<StJpegParser::Image> anImg = new StJpegParser::Image(); anImg->Data = aData - 2; for(;;) { // search for the next marker in the file ++aData; // one byte forward size_t aSkippedBytes = 0; unsigned char aMarker = 0; for(; aData < aDataEnd; ++aSkippedBytes, ++aData) { aMarker = aData[0]; if(aData[-1] == 0xFF && aMarker != 0xFF && aMarker != 0x00) { ++aData; // skip marker id byte break; } } //ST_DEBUG_LOG(" #" + theImgCount + "." + theDepth + " [" + markerString(aMarker) + "] at position " + size_t(aData - myBuffer) + " / " + myLength); /// if(aMarker == M_EOI) { //ST_DEBUG_LOG("Jpeg, EOI at position " + size_t(aData - myBuffer) + " / " + myLength); anImg->Length = size_t(aData - anImg->Data); return anImg; } else if(aMarker == M_SOI) { // here the subimage (thumbnail)... //ST_DEBUG_LOG("Jpeg, SOI at position " + size_t(aData - myBuffer) + " / " + myLength); anImg->Thumb = StJpegParser::parseImage(theImgCount, theDepth + 1, aData - 2, false); if(!anImg->Thumb.isNull()) { //ST_DEBUG_LOG("anImg->Thumb->Length= " + anImg->Thumb->Length); aData += anImg->Thumb->Length - 2; } continue; } if(aData + 2 >= aDataEnd) { ST_DEBUG_LOG("Corrupt jpeg file or error in parser"); if(myImages.isNull()) { anImg->Data = myBuffer; anImg->Length = myLength; } return anImg; } else if(aSkippedBytes > 10) { //ST_DEBUG_LOG("Extraneous " + (aSkippedBytes - 1) + " padding bytes before section " + aMarker); } // read the length of the section (including these 2 bytes but excluding marker) const int anItemLen = StAlienData::Get16uBE(aData); if(anItemLen < 3 || (aData + anItemLen) > aDataEnd) { //ST_DEBUG_LOG("Invalid marker " + aMarker + " in jpeg (item lenght = " + anItemLen // + " from position " + int(aDataEnd - aData - 2) + ')'); // just ignore probably unknown sections continue; } switch(aMarker) { case M_SOF0: case M_SOF1: case M_SOF2: case M_SOF3: { if(anItemLen >= 7) { anImg->SizeY = StAlienData::Get16uBE(aData + 2 + 1); anImg->SizeX = StAlienData::Get16uBE(aData + 2 + 3); //ST_DEBUG_LOG(" SOF " + anImg->SizeX + "x" + anImg->SizeY); } aData += anItemLen; break; } case M_DRI: { if(anItemLen == 4) { //const int16_t aNbRestartBlocks = anImg->SizeY = StAlienData::Get16uBE(aData + 2); } aData += anItemLen; break; } case M_SOS: { // here the image data... //ST_DEBUG_LOG("Jpeg, SOS at position " + size_t(aData - myBuffer - 1) + " / " + myLength); aData += anItemLen; break; } case M_RST0: case M_RST1: case M_RST2: case M_RST3: case M_RST4: case M_RST5: case M_RST6: case M_RST7: { // aData += aNbRestartBlocks * aMcuSize; break; } case M_JFIF: { if(anItemLen >= 16 && stAreEqual(aData + 2, "JFIF\0", 5)) { myOffsets[Offset_Jfif] = aData - myBuffer - 2; //const int8_t aVerMaj = (int8_t )aData[7]; //const int8_t aVerMin = (int8_t )aData[8]; const JfifUnitsXY aUnits = (JfifUnitsXY )aData[9]; const uint16_t aDensityX = StAlienData::Get16uBE(aData + 10); const uint16_t aDensityY = StAlienData::Get16uBE(aData + 12); //const int8_t aThumbX = (int8_t )aData[14]; //const int8_t aThumbY = (int8_t )aData[15]; if(aUnits == JfifUnitsXY_AspectRatio) { anImg->ParX = aDensityX; anImg->ParY = aDensityY; } //ST_DEBUG_LOG(" ## JFIF" + aVerMaj + "." + aVerMin + " u" + (int )aUnits + " " + aDensityX + "x" + aDensityY // + " thumb " + aThumbX + "x" + aThumbY); } else if(stAreEqual(aData + 2, "JFXX\0", 5)) { // JFIF extension } aData += anItemLen; break; } case M_EXIF: case M_APP2: { myOffsets[aMarker == M_EXIF ? Offset_Exif : Offset_ExifExtra] = aData - myBuffer - 2; // there can be different section using the same marker if(stAreEqual(aData + 2, "Exif\0\0", 6)) { //ST_DEBUG_LOG("Exif section..."); StHandle<StExifDir> aSubDir = new StExifDir(); anImg->Exif.add(aSubDir); if(!aSubDir->parseExif(anImg->Exif, aData + 8, anItemLen - 8)) { // } } else if(stAreEqual(aData + 2, "MPF\0", 4)) { // MP Extensions (MPO) StHandle<StExifDir> aSubDir = new StExifDir(); aSubDir->Type = StExifDir::DType_MPO; anImg->Exif.add(aSubDir); if(!aSubDir->parseExif(anImg->Exif, aData + 6, anItemLen - 6)) { // } } else if(stAreEqual(aData + 2, "http:", 5)) { //ST_DEBUG_LOG("Image cotains XMP section"); } else { //ST_DEBUG_LOG(" @@@ APP2 " + StString((char* )aData + 2)); } // skip already read bytes aData += anItemLen; break; } case M_APP3: { if(anItemLen >= 16 && stAreEqual(aData + 2, "_JPSJPS_", 8)) { // outdated VRex section myOffsets[Offset_Jps] = aData - myBuffer - 2; //ST_DEBUG_LOG("Jpeg, _JPSJPS_ section (len= )" + anItemLen); //const uint16_t aBlockLen = StAlienData::Get16uBE(aData + 10); const uint32_t aStereoDesc = StAlienData::Get32uBE(aData + 12); #define SD_LAYOUT_INTERLEAVED 0x00000100 #define SD_LAYOUT_SIDEBYSIDE 0x00000200 #define SD_LAYOUT_OVERUNDER 0x00000300 #define SD_LAYOUT_ANAGLYPH 0x00000400 #define SD_HALF_HEIGHT 0x00010000 #define SD_HALF_WIDTH 0x00020000 #define SD_LEFT_FIELD_FIRST 0x00040000 if(aStereoDesc & 0x00000001) { const bool isLeftFirst = (aStereoDesc & SD_LEFT_FIELD_FIRST) != 0; switch(aStereoDesc & 0x0000FF00) { case SD_LAYOUT_INTERLEAVED: myStFormat = ST_V_SRC_ROW_INTERLACE; break; case SD_LAYOUT_SIDEBYSIDE: myStFormat = isLeftFirst ? ST_V_SRC_PARALLEL_PAIR : ST_V_SRC_SIDE_BY_SIDE; break; case SD_LAYOUT_OVERUNDER: myStFormat = isLeftFirst ? ST_V_SRC_OVER_UNDER_LR : ST_V_SRC_OVER_UNDER_RL; break; case SD_LAYOUT_ANAGLYPH: myStFormat = ST_V_SRC_ANAGLYPH_RED_CYAN; break; default: break; } } else { myStFormat = ST_V_SRC_MONO; } if(anItemLen > 18) { const uint16_t aStringLen = StAlienData::Get16uBE(aData + 16); char* aStrData = (char* )aData + 18; myJpsComment = StString(aStrData, aStringLen); } } // skip already read bytes aData += anItemLen; break; } case M_DQT: { myOffsets[Offset_Dqt] = aData - myBuffer - 2; aData += anItemLen; break; } case M_APP4: case M_APP5: case M_APP6: case M_APP7: case M_APP8: case M_APP9: case M_APP10: case M_APP11: case M_APP12: case M_APP13: case M_APP14: case M_APP15: case M_DHT: { aData += anItemLen; break; } case M_COM: { myOffsets[Offset_Comment] = aData - myBuffer - 2; if(anItemLen > 2) { myComment = StString((char* )aData + 2, anItemLen - 2); } //ST_DEBUG_LOG("StJpegParser, comment= '" + myComment + "'"); aData += anItemLen; break; } default: { // carefully skip unknown sections //aData += anItemLen; break; } } } }
void StBrowserPlugin::stWindowLoop() { // do not load plugin until it is placed on screen StWindow aParentWin(myResMgr, myParentWin); for(;;) { #ifndef _WIN32 const int32_t anActiveNb = #endif ST_PLUGIN_QUEUE.increment(); if(aParentWin.isParentOnScreen() #ifndef _WIN32 || anActiveNb <= 1 #endif ) { break; } ST_PLUGIN_QUEUE.decrement(); StThread::sleep(10); if(myToQuit) { return; } } // Load image viewer myStApp = new StImageViewer(myResMgr, myParentWin, new StOpenInfo()); if(!myStApp->open()) { ST_PLUGIN_QUEUE.decrement(); myStApp.nullify(); return; } ST_PLUGIN_QUEUE.decrement(); bool isFileOpened = false; bool isFullscreen = false; bool isFullLoaded = false; myIsActive = true; for(;;) { if(myStApp->closingDown()) { myStApp.nullify(); myIsActive = false; return; } myIsActive = myStApp->isActive(); if(myToQuit) { myStApp->exit(0); } else if(!isFileOpened && myIsActive) { // load the image StMutexAuto aLock(myMutex); if(myPreviewUrl.isEmpty()) { if(!myFullPath.isEmpty()) { myOpenInfo.setPath(myFullPath); aLock.unlock(); myStApp->open(myOpenInfo); isFileOpened = true; } } else if(!myPreviewPath.isEmpty()) { myOpenInfo.setPath(myPreviewPath); aLock.unlock(); myStApp->open(myOpenInfo); isFileOpened = true; } } StHandle<StWindow> aWin = myStApp->getMainWindow(); if(myIsActive) { aWin->show(); } else { aWin->hide(); } myStApp->processEvents(); if(aWin->isFullScreen()) { StMutexAuto aLock(myMutex); if(!isFullscreen && !myFullPath.isEmpty()) { myOpenInfo.setPath(myFullPath); aLock.unlock(); myStApp->open(myOpenInfo); isFullscreen = true; } else if(!isFullLoaded && NPNFuncs.pluginthreadasynccall != NULL) { aLock.unlock(); NPNFuncs.pluginthreadasynccall(nppInstance, StBrowserPlugin::doLoadFullSize, this); isFullLoaded = true; } } else if(isFullscreen) { StMutexAuto aLock(myMutex); if(!myPreviewPath.isEmpty()) { myOpenInfo.setPath(myPreviewPath); aLock.unlock(); myStApp->open(myOpenInfo); isFullscreen = false; } } } }
StOutAnaglyph::StOutAnaglyph(const StNativeWin_t theParentWindow) : StWindow(theParentWindow), mySettings(new StSettings(ST_OUT_PLUGIN_NAME)), myFrBuffer(new StGLStereoFrameBuffer()), myStereoProgram(NULL), mySimpleAnaglyph("Anaglyph Simple"), myGrayAnaglyph("Anaglyph Gray"), myTrueAnaglyph("Anaglyph True"), myOptimAnaglyph("Anaglyph Optimized"), myYellowAnaglyph("Anaglyph Yellow"), myYellowDubiosAnaglyph("Anaglyph Yellow Dubios"), myGreenAnaglyph("Anaglyph Green"), myToSavePlacement(theParentWindow == (StNativeWin_t )NULL), myToCompressMem(myInstancesNb.increment() > 1), myIsBroken(false) { StTranslations aLangMap(ST_OUT_PLUGIN_NAME); myStereoProgram = &mySimpleAnaglyph; // about string StString& aTitle = aLangMap.changeValueId(STTR_PLUGIN_TITLE, "sView - Anaglyph Output module"); StString& aVerString = aLangMap.changeValueId(STTR_VERSION_STRING, "version"); StString& aDescr = aLangMap.changeValueId(STTR_PLUGIN_DESCRIPTION, "(C) 2007-2014 Kirill Gavrilov <*****@*****.**>\nOfficial site: www.sview.ru\n\nThis library distributed under LGPL3.0"); myAbout = aTitle + '\n' + aVerString + ": " + StVersionInfo::getSDKVersionString() + "\n \n" + aDescr; // devices list StHandle<StOutDevice> aDevice = new StOutDevice(); aDevice->PluginId = ST_OUT_PLUGIN_NAME; aDevice->DeviceId = "Anaglyph"; aDevice->Priority = ST_DEVICE_SUPPORT_LOW; // anaglyph could be run on every display... aDevice->Name = aLangMap.changeValueId(STTR_ANAGLYPH_NAME, "Anaglyph glasses"); aDevice->Desc = aLangMap.changeValueId(STTR_ANAGLYPH_DESC, "Simple glasses with color-filters"); myDevices.add(aDevice); // Glasses switch option StHandle<StEnumParam> aGlasses = new StEnumParam(GLASSES_TYPE_REDCYAN, aLangMap.changeValueId(STTR_ANAGLYPH_GLASSES, "Glasses type")); aGlasses->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN, "Red-cyan")); aGlasses->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_YELLOW, "Yellow-Blue")); aGlasses->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_GREEN, "Green-Magenta")); aGlasses->signals.onChanged.connect(this, &StOutAnaglyph::doSetShader); params.Glasses = aGlasses; // Red-cyan filter switch option StHandle<StEnumParam> aFilterRC = new StEnumParam(REDCYAN_MODE_SIMPLE, aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN_MENU, "Red-Cyan filter")); aFilterRC->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN_SIMPLE, "Simple")); aFilterRC->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN_OPTIM, "Optimized")); aFilterRC->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN_GRAY, "Grayed")); aFilterRC->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_REDCYAN_DARK, "Dark")); aFilterRC->signals.onChanged.connect(this, &StOutAnaglyph::doSetShader); params.RedCyan = aFilterRC; // Amber-Blue filter switch option StHandle<StEnumParam> aFilterAB = new StEnumParam(AMBERBLUE_MODE_SIMPLE, aLangMap.changeValueId(STTR_ANAGLYPH_AMBERBLUE_MENU, "Yellow filter")); aFilterAB->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_AMBERBLUE_SIMPLE, "Simple")); aFilterAB->changeValues().add(aLangMap.changeValueId(STTR_ANAGLYPH_AMBERBLUE_DUBIOS, "Dubios")); aFilterAB->signals.onChanged.connect(this, &StOutAnaglyph::doSetShader); params.AmberBlue = aFilterAB; // load window position StRect<int32_t> aRect(256, 768, 256, 1024); mySettings->loadInt32Rect(ST_SETTING_WINDOWPOS, aRect); StWindow::setPlacement(aRect, true); StWindow::setTitle("sView - Anaglyph Renderer"); // load glasses settings mySettings->loadParam(ST_SETTING_GLASSES, params.Glasses); mySettings->loadParam(ST_SETTING_REDCYAN, params.RedCyan); mySettings->loadParam(ST_SETTING_AMBERBLUE, params.AmberBlue); }
bool StApplication::open() { if(!myWindow.isNull()) { return true; } StSettings aGlobalSettings(myResMgr, "sview"); if(!mySwitchTo.isNull()) { myRendId = mySwitchTo->getRendererId(); myWindow = mySwitchTo; mySwitchTo.nullify(); aGlobalSettings.saveString(ST_SETTING_RENDERER, myRendId); aGlobalSettings.saveBool (ST_SETTING_RENDERER_AUTO, false); } else { if(myRenderers.isEmpty()) { myWindow = new StWindow(myResMgr, myWinParent); myWindow->setMessagesQueue(myMsgQueue); myWindow->params.VSyncMode = params.VSyncMode; } else { bool isAuto = myRendId.isEqualsIgnoreCase(ST_SETTING_AUTO_VALUE); if(!isAuto) { for(size_t anIter = 0; anIter < myRenderers.size(); ++anIter) { StHandle<StWindow> aWin = myRenderers[anIter]; if(myRendId == aWin->getRendererId()) { myWindow = aWin; aGlobalSettings.saveString(ST_SETTING_RENDERER, myRendId); aGlobalSettings.saveBool (ST_SETTING_RENDERER_AUTO, isAuto); break; } } if(myWindow.isNull()) { stError(StString("Output with id '" + myRendId + "' is not found.")); isAuto = true; } } if(isAuto) { // autodetection aGlobalSettings.saveString(ST_SETTING_RENDERER, ST_SETTING_AUTO_VALUE); aGlobalSettings.saveBool (ST_SETTING_RENDERER_AUTO, isAuto); myWindow = myRenderers[0]; if(!myDevices.isEmpty()) { StHandle<StOutDevice> aBestDev = myDevices[0]; for(size_t aDevIter = 0; aDevIter < myDevices.size(); ++aDevIter) { const StHandle<StOutDevice>& aDev = myDevices[aDevIter]; if(aDev->Priority > aBestDev->Priority) { aBestDev = aDev; } } for(size_t anIter = 0; anIter < myRenderers.size(); ++anIter) { const StHandle<StWindow>& aWin = myRenderers[anIter]; if(aBestDev->PluginId == aWin->getRendererId()) { myWindow = aWin; myWindow->setDevice(aBestDev->DeviceId); break; } } } } } myWindow->setTitle(myTitle); } // synchronize devices enumeration const StString aPluginId = myWindow->getRendererId(); const StString aDeviceId = myWindow->getDeviceId(); for(size_t aDevIter = 0; aDevIter < myDevices.size(); ++aDevIter) { const StHandle<StOutDevice>& aDev = myDevices[aDevIter]; if(aPluginId == aDev->PluginId && aDeviceId == aDev->DeviceId) { params.ActiveDevice->setValue((int32_t )aDevIter); break; } } // setup GL options before window creation const StWinAttr anAttribs[] = { StWinAttr_GlDebug, (StWinAttr )myGlDebug, StWinAttr_NULL }; myWindow->setAttributes(anAttribs); myIsOpened = myWindow->create(); if(myIsOpened) { // connect slots myWindow->signals.onRedraw = stSlot(this, &StApplication::doDrawProxy); myWindow->signals.onClose = stSlot(this, &StApplication::doClose); myWindow->signals.onPause = stSlot(this, &StApplication::doPause); myWindow->signals.onResize = stSlot(this, &StApplication::doResize); myWindow->signals.onAction = stSlot(this, &StApplication::doAction); myWindow->signals.onKeyDown = stSlot(this, &StApplication::doKeyDown); myWindow->signals.onKeyUp = stSlot(this, &StApplication::doKeyUp); myWindow->signals.onKeyHold = stSlot(this, &StApplication::doKeyHold); myWindow->signals.onMouseDown = stSlot(this, &StApplication::doMouseDown); myWindow->signals.onMouseUp = stSlot(this, &StApplication::doMouseUp); myWindow->signals.onTouch = stSlot(this, &StApplication::doTouch); myWindow->signals.onGesture = stSlot(this, &StApplication::doGesture); myWindow->signals.onScroll = stSlot(this, &StApplication::doScroll); myWindow->signals.onFileDrop = stSlot(this, &StApplication::doFileDrop); myWindow->signals.onNavigate = stSlot(this, &StApplication::doNavigate); } return myIsOpened; }
StHandle<StOpenInfo> StApplication::parseProcessArguments() { StHandle<StOpenInfo> anInfo = new StOpenInfo(); StArrayList<StString> anArguments = StProcess::getArguments(); StArgumentsMap anOpenFileArgs; size_t aFilesCount = 0; bool isFilesSection = false; const StString ARGUMENT_FILES_SECTION = '-'; const StString ARGUMENT_ANY = "--"; const StString ARGUMENT_HELP = "help"; const StString ARGUMENT_FILE = "file"; const StString ARGUMENT_LEFT_VIEW = "left"; const StString ARGUMENT_RIGHT_VIEW = "right"; // parse extra parameters for(size_t aParamIter = 1; aParamIter < anArguments.size(); ++aParamIter) { StString aParam = anArguments[aParamIter]; ///ST_DEBUG_LOG("aParam= '" + aParam + "'"); if(isFilesSection) { // file name StString aFilePath = StProcess::getAbsolutePath(aParam); anOpenFileArgs.add(StArgument(ARGUMENT_FILE + aFilesCount++, aFilePath)); if(!anInfo->hasPath()) { // first file determines MIME type (needed to autoselect Drawer plugin) anInfo->setPath(aFilePath); } } else if(aParam == ARGUMENT_FILES_SECTION) { isFilesSection = true; } else if(aParam.isStartsWith(ARGUMENT_ANY)) { // argument StArgument anArg; anArg.parseString(aParam.subString(2, aParam.getLength())); // cut suffix -- if(anArg.getKey().isEqualsIgnoreCase(ARGUMENT_HELP)) { return NULL; } else if(anArg.getKey().isEqualsIgnoreCase(ARGUMENT_LEFT_VIEW)) { // left view anArg.setValue(StProcess::getAbsolutePath(anArg.getValue())); anOpenFileArgs.add(anArg); anInfo->setPath(anArg.getValue()); // left file always determines MIME type } else if(anArg.getKey().isEqualsIgnoreCase(ARGUMENT_RIGHT_VIEW)) { // right view anArg.setValue(StProcess::getAbsolutePath(anArg.getValue())); anOpenFileArgs.add(anArg); if(!anInfo->hasPath()) { anInfo->setPath(anArg.getValue()); } } else { // pass argument unchanged anOpenFileArgs.add(anArg); } } else { // file name StString aFilePath = StProcess::getAbsolutePath(aParam); anOpenFileArgs.add(StArgument(ARGUMENT_FILE + aFilesCount++, aFilePath)); if(!anInfo->hasPath()) { // first file determines MIME type (needed to autoselect Drawer plugin) anInfo->setPath(aFilePath); } } } anInfo->setArgumentsMap(anOpenFileArgs); return anInfo; }
void StPlayList::open(const StCString& thePath, const StCString& theItem) { StMutexAuto anAutoLock(myMutex); // check if it is recently played playlist bool hasTarget = !theItem.isEmpty(); StString aTarget = hasTarget ? theItem : thePath; if(!hasTarget) { for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { const StHandle<StRecentItem>& aRecent = myRecent[anIter]; const StHandle<StFileNode>& aFile = aRecent->File; if(aFile->size() != 1) { continue; } if(thePath.isEquals(aFile->getPath())) { hasTarget = true; aTarget = aFile->getValue(0)->getSubPath(); break; } } } clear(); int aSearchDeep = myRecursionDeep; StString aFolderPath; StString aFileName; if(StFolder::isFolder(thePath)) { // add all files from the folder and subfolders aFolderPath = thePath; aSearchDeep = myRecursionDeep; myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list } else if(StFileNode::isFileExists(thePath)) { // search only current folder StFileNode::getFolderAndFile(thePath, aFolderPath, aFileName); aSearchDeep = 1; bool hasSupportedExt = false; StString anExt = StFileNode::getExtension(aFileName); for(size_t anExtId = 0; anExtId < myExtensions.size() && !hasSupportedExt; ++anExtId) { hasSupportedExt = anExt.isEqualsIgnoreCase(myExtensions[anExtId]); } // parse m3u playlist if(anExt.isEqualsIgnoreCase(stCString("m3u")) || anExt.isEqualsIgnoreCase(stCString("m3u8"))) { StHandle<StRawFile> aRawFile = new StRawFile(thePath); if(aRawFile->readFile()) { StFolder* aPlsFolder = new StFolder(aFolderPath, &myFoldersRoot); myFoldersRoot.add(aPlsFolder); StString aTitle; for(char* anIter = skipBOM((char* )aRawFile->getBuffer()); anIter != NULL;) { anIter = parseM3UIter(anIter, aPlsFolder, aTitle); } aRawFile.nullify(); if(myFirst != nullptr && myFirst->getNext() == nullptr) { const StString aFirstPath = myFirst->getPath(); StString anItemExt = StFileNode::getExtension(aFirstPath); if(anItemExt.isEqualsIgnoreCase(stCString("m3u")) || anItemExt.isEqualsIgnoreCase(stCString("m3u8"))) { aRawFile = new StRawFile(aFirstPath); if(aRawFile->readFile()) { for(char* anIter = skipBOM((char* )aRawFile->getBuffer()); anIter != NULL;) { anIter = parseM3UIter(anIter, NULL, aTitle); } remove(aFirstPath, false); } aRawFile.nullify(); } } myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list if(hasTarget) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); return; } } if(!hasSupportedExt) { // file with unsupported extension? StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addPlayItem(new StPlayItem(aFileNode, myDefStParams)); } } else { // not a filesystem element - probably url or invalid path StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addRecentFile(*aFileNode); // append to recent files list addPlayItem(new StPlayItem(aFileNode, myDefStParams)); anAutoLock.unlock(); signals.onPlaylistChange(); return; } StFolder* aSubFolder = new StFolder(aFolderPath, &myFoldersRoot); aSubFolder->init(myExtensions, aSearchDeep); myFoldersRoot.add(aSubFolder); addToPlayList(aSubFolder); myCurrent = myFirst; if(hasTarget || !aFileName.isEmpty()) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; if(myPlsFile.isNull()) { addRecentFile(*anItem->getFileNode()); // append to recent files list } break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); }