NCSEcwReadStatus ECWAsyncReader::RefreshCB( NCSFileView *pFileView ) { NCSFileViewSetInfo *psVSI = NULL; NCScbmGetViewInfo( pFileView, &psVSI ); if( psVSI != NULL ) { CPLDebug( "ECW", "RefreshCB(): BlockCounts=%d/%d/%d/%d", psVSI->nBlocksAvailableAtSetView, psVSI->nBlocksAvailable, psVSI->nMissedBlocksDuringRead, psVSI->nBlocksInView ); } /* -------------------------------------------------------------------- */ /* Identify the reader we are responding on behalf of. */ /* -------------------------------------------------------------------- */ CNCSJP2FileView *poFileView = (CNCSJP2FileView *) pFileView; ECWAsyncReader *poReader = (ECWAsyncReader *)poFileView->GetClientData(); /* -------------------------------------------------------------------- */ /* Acquire the async reader mutex. Currently we make no */ /* arrangements for failure to acquire it. */ /* -------------------------------------------------------------------- */ { CPLMutexHolderD( &(poReader->hMutex) ); /* -------------------------------------------------------------------- */ /* Mark the buffer as updated unless we are already complete. */ /* It seems the Update callback keeps getting called even when */ /* no new data has arrived after completion so we don't want to */ /* trigger new work elsewhere in that case. */ /* */ /* Also record whether we are now complete. */ /* -------------------------------------------------------------------- */ if( !poReader->bComplete ) poReader->bUpdateReady = TRUE; if( psVSI->nBlocksAvailable == psVSI->nBlocksInView ) poReader->bComplete = TRUE; } /* Call CPLCleanupTLS explicitly since this thread isn't managed */ /* by CPL. This will free the resources taken by the above CPLDebug */ if( poReader->bComplete ) CPLCleanupTLS(); return NCSECW_READ_OK; }
/* * Class: com_ermapper_ecw_JNCSFile * Method: ECWClose * Signature: (Z)V */ JNIEXPORT void JNICALL Java_com_ermapper_ecw_JNCSFile_ECWClose (JNIEnv *pEnv , jobject JNCSFile, jboolean bFreeCache) { NCSError nError; NCSJNIInfo *pJNIInfo = NULL; pJNIInfo = (NCSJNIInfo *)(*pEnv)->GetLongField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNativeDataPointer); if (pJNIInfo != NULL) { NCSFileViewSetInfo *pViewInfo; NCScbmGetViewInfo(pJNIInfo->pFileView, &pViewInfo); // Clear the Java object members. (*pEnv)->SetIntField (pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDWidth, (jint)0 ); (*pEnv)->SetIntField (pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDHeight, (jint)0 ); (*pEnv)->SetIntField (pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNumberOfBands, (jint)0); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCompressionRate, (jdouble)0.0 ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellIncrementX, (jdouble)0.0 ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellIncrementY, (jdouble)0.0 ); (*pEnv)->SetIntField (pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellSizeUnits, (jint)0 ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDOriginX, (jdouble)0.0 ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDOriginY, (jdouble)0.0 ); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDDatum, (*pEnv)->NewStringUTF(pEnv, "")); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDProjection, (*pEnv)->NewStringUTF(pEnv, "")); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFilename, NULL); (*pEnv)->SetBooleanField(pEnv,JNCSFile, pGlobalJNCSFieldIDs->jIDIsOpen, JNI_FALSE); (*pEnv)->SetLongField (pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNativeDataPointer, (jlong)0); (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFileType, (jint)0 ); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFileMimeType, NULL ); // Clean up any global refs //(*pEnv)->DeleteGlobalRef(pEnv, pJNIInfo->ECWFile); (*pEnv)->DeleteGlobalRef(pEnv, pViewInfo->pClientData); nError = NCScbmCloseFileViewEx(pJNIInfo->pFileView, bFreeCache); pJNIInfo->pFileView = NULL; NCSFree(pJNIInfo); } return; }
JNIEXPORT jshort JNICALL Java_com_ermapper_ecw_JNCSFile_ECWGetPercentComplete (JNIEnv *pEnv, jobject JNCSFile) { NCSFileViewSetInfo *pViewInfo = NULL; NCSJNIInfo *pJNIInfo = NULL; pJNIInfo = (NCSJNIInfo *)(*pEnv)->GetLongField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNativeDataPointer); if (!pJNIInfo) return 0; if (pJNIInfo->pFileView) { NCScbmGetViewInfo(pJNIInfo->pFileView, &pViewInfo); if (pViewInfo) { return (jshort)((pViewInfo->nBlocksAvailable / (double)pViewInfo->nBlocksInView) * 100); } } else { return 0; } return 0; }
/* * Class: com_ermapper_ecw_JNCSFile * Method: ECWOpen * Signature: (Ljava/lang/String;Z)I */ JNIEXPORT jint JNICALL Java_com_ermapper_ecw_JNCSFile_ECWOpen (JNIEnv *pEnv, jobject JNCSFile, jstring Filename, jboolean bProgressive) { const char *pFilename = (*pEnv)->GetStringUTFChars(pEnv, Filename, (jboolean *)NULL); NCSFileView *pNCSFileView = NULL; NCSFileViewSetInfo *pNCSFileViewSetInfo = NULL; NCSError nError; if (bProgressive) { nError = NCScbmOpenFileView((char *)pFilename, &pNCSFileView, NCSJNIRefreshCallback); } else { nError = NCScbmOpenFileView((char *)pFilename, &pNCSFileView, NULL); } if (NCS_FAILED(nError)) { // Return the short filename, since people dont like diplaying the full ecwp url char *pProtocol, *pHost, *pECWFilename, *pShortFileName; int nProtocolLength, nHostLength, nFilenameLength; NCSecwNetBreakdownUrl((char *)pFilename, &pProtocol, &nProtocolLength, &pHost, &nHostLength, &pECWFilename, &nFilenameLength); if (pECWFilename && nFilenameLength > 0 && (strstr(pECWFilename, "/") || strstr(pECWFilename, "\\"))) { int len = strlen(pECWFilename), index = 0; for (index=len; index > 0; index--) { pShortFileName = &pECWFilename[index]; if (pECWFilename[index] == '\\' || pECWFilename[index] == '/') { pShortFileName ++; break; } } } else { pShortFileName = (char *)pFilename; } NCSFormatErrorText(NCS_FILE_OPEN_FAILED, pShortFileName, NCSGetLastErrorText(nError)); return NCS_FILE_OPEN_FAILED; } else { NCSJNIInfo *pJNIInfo = NULL; char *pMimeType = NULL; NCSFileViewFileInfo *pNCSFileInfo = NULL; nError = NCSCreateJNIInfoStruct(pEnv, JNCSFile, pNCSFileView, &pJNIInfo); NCScbmGetViewFileInfo(pNCSFileView, &pNCSFileInfo); // Set the properties in the actual Java object (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDWidth, (jint)pNCSFileInfo->nSizeX ); (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDHeight, (jint)pNCSFileInfo->nSizeY ); (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNumberOfBands, (jint)pNCSFileInfo->nBands); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCompressionRate, (jdouble)pNCSFileInfo->nCompressionRate ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellIncrementX, (jdouble)pNCSFileInfo->fCellIncrementX ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellIncrementY, (jdouble)pNCSFileInfo->fCellIncrementY ); (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDCellSizeUnits, (jint)pNCSFileInfo->eCellSizeUnits); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDOriginX, (jdouble)pNCSFileInfo->fOriginX ); (*pEnv)->SetDoubleField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDOriginY, (jdouble)pNCSFileInfo->fOriginY ); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDDatum, (*pEnv)->NewStringUTF(pEnv, pNCSFileInfo->szDatum)); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDProjection, (*pEnv)->NewStringUTF(pEnv, pNCSFileInfo->szProjection)); (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFilename, Filename); (*pEnv)->SetBooleanField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDIsOpen, JNI_TRUE); (*pEnv)->SetLongField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDNativeDataPointer, (jlong)pJNIInfo); (*pEnv)->SetIntField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFileType, (jint)NCScbmGetFileType(pNCSFileView) ); pMimeType = NCScbmGetFileMimeType(pNCSFileView); if( pMimeType ) { (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFileMimeType, (*pEnv)->NewStringUTF(pEnv, pMimeType) ); NCSFree( pMimeType ); pMimeType = NULL; } else { (*pEnv)->SetObjectField(pEnv, JNCSFile, pGlobalJNCSFieldIDs->jIDFileMimeType, NULL ); } } (*pEnv)->ReleaseStringUTFChars(pEnv, Filename, (const char *)pFilename); NCScbmGetViewInfo(pNCSFileView, &pNCSFileViewSetInfo); pNCSFileViewSetInfo->pClientData = (void *)(*pEnv)->NewGlobalRef(pEnv, JNCSFile); return NCS_SUCCESS; }
/* * There is so much that can go wrong in this call, that is why there is so much error checking. * * Class: None * Method: NCSJNIRefreshCallback * Signature: */ NCSEcwReadStatus NCSJNIRefreshCallback(NCSFileView *pNCSFileView) { NCSFileViewSetInfo *pViewInfo; NCSJNIInfo *pJNIInfo; jint nError; JNIEnv *pEnv; jclass EcwObjectClass = NULL; jobject pECWFile = NULL; NCScbmGetViewInfo(pNCSFileView, &pViewInfo); // Must attach to the vm thread before calling any java methods. nError = (*pJavaVirtualMachineInst)->AttachCurrentThread(pJavaVirtualMachineInst, (void **)&pEnv, NULL); if (nError != 0) { char Message[] = "The ECW JNI interface could not attach to the current thread in\n" "the Java virtual machine. Please refer to the Image Web Server\n" "Java SDK documentation for more information about JVM threads.\n\n" "Progressive imagery will not be available."; #ifdef WIN32 MessageBox(GetActiveWindow(), OS_STRING(Message), NCS_T("JNCSFile VM Error"), MB_OK); #else fprintf(stderr, "JNCSFile VM Error : %s\n", Message); #endif return NCSECW_READ_FAILED; } // Make sure we got a view info struct. if (!pViewInfo) { NCSJNIThrowException(pEnv, "java/lang/Exception", "ECW JNI component could not obtain the NCSViewInfo pointer from the NCSFileView. No refreshUpdate() will occur."); (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_FAILED; } // The file is the global reference stashed in the client data pointer. pECWFile = (jobject)pViewInfo->pClientData; // Check to make sure that the ECW object has not been free'd or garbaged collected. This is only valid for JNI 1.2 if ((*pEnv)->IsSameObject(pEnv, pECWFile/*pViewInfo->pClientData*/, NULL) == JNI_TRUE) { (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_FAILED; } // Use the valid reference to the object, to obtain the data pointer. pJNIInfo = (NCSJNIInfo *)(*pEnv)->GetLongField(pEnv, pViewInfo->pClientData, pGlobalJNCSFieldIDs->jIDNativeDataPointer); if (!pJNIInfo) { NCSJNIThrowException(pEnv, "java/lang/Exception", "The ECW JNI component could not obtain the client data pointer from the NCSViewInfo struct. No refreshUpdate() will occur."); (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_FAILED; } EcwObjectClass = (*pEnv)->GetObjectClass(pEnv, pECWFile/*pJNIInfo->ECWFile*/); if (EcwObjectClass == NULL) { NCSJNIThrowException(pEnv, "java/lang/Exception", "The ECW JNI component could not determine the class signature of the ECW object."); (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_FAILED; } (*pEnv)->DeleteLocalRef(pEnv, EcwObjectClass); //Call the "refreshUpdate" method on this object, if it implements the JNCSProgressiveUpdate interface. if (pGlobalJNCSFieldIDs->jIDRefreshUpdateMethod) { (*pEnv)->CallVoidMethod(pEnv, \ pECWFile, \ pGlobalJNCSFieldIDs->jIDRefreshUpdateMethod, \ pViewInfo->nSizeX, pViewInfo->nSizeY, \ pViewInfo->fTopX, pViewInfo->fLeftY, \ pViewInfo->fBottomX, pViewInfo->fRightY); } else { NCSJNIThrowException(pEnv, "java/lang/ClassNotFoundException", "'refreshUpdate' method not found. Derived classes must implement the interface 'JNCSProgressiveUpdate' to use progressive imagery."); (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_FAILED; } (*pJavaVirtualMachineInst)->DetachCurrentThread(pJavaVirtualMachineInst); return NCSECW_READ_OK; }