CachedPage::UnitPtr Jpeg2000Pager::fetchUnit(DataRequest* pOriginalRequest) { if (pOriginalRequest == NULL) { return CachedPage::UnitPtr(); } // Check for interleave conversions, which are not supported by this pager const RasterElement* pRaster = getRasterElement(); VERIFYRV(pRaster != NULL, CachedPage::UnitPtr()); const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFYRV(pDescriptor != NULL, CachedPage::UnitPtr()); const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); VERIFYRV(pFileDescriptor != NULL, CachedPage::UnitPtr()); if (pFileDescriptor->getBandCount() > 1) { InterleaveFormatType requestedInterleave = pOriginalRequest->getInterleaveFormat(); InterleaveFormatType fileInterleave = pFileDescriptor->getInterleaveFormat(); if (requestedInterleave != fileInterleave) { return CachedPage::UnitPtr(); } VERIFYRV(requestedInterleave == BIP, CachedPage::UnitPtr()); // The JPEG2000 data is stored BIP } // Get and validate the extents of the data to be loaded DimensionDescriptor startRow = pOriginalRequest->getStartRow(); DimensionDescriptor stopRow = pOriginalRequest->getStopRow(); unsigned int concurrentRows = pOriginalRequest->getConcurrentRows(); DimensionDescriptor startColumn = pOriginalRequest->getStartColumn(); DimensionDescriptor stopColumn = pOriginalRequest->getStopColumn(); unsigned int concurrentColumns = pOriginalRequest->getConcurrentColumns(); DimensionDescriptor startBand = pOriginalRequest->getStartBand(); DimensionDescriptor stopBand = pOriginalRequest->getStopBand(); if ((startRow.isOnDiskNumberValid() == false) || (stopRow.isOnDiskNumberValid() == false) || (startColumn.isOnDiskNumberValid() == false) || (stopColumn.isOnDiskNumberValid() == false) || (startBand.isOnDiskNumberValid() == false) || (stopBand.isOnDiskNumberValid() == false)) { return CachedPage::UnitPtr(); } if ((startRow.getOnDiskNumber() > stopRow.getOnDiskNumber()) || (startColumn.getOnDiskNumber() > stopColumn.getOnDiskNumber()) || (startBand.getOnDiskNumber() > stopBand.getOnDiskNumber())) { return CachedPage::UnitPtr(); } if ((startRow.getActiveNumber() + concurrentRows - 1) > stopRow.getActiveNumber()) { concurrentRows = stopRow.getActiveNumber() - startRow.getActiveNumber() + 1; } if ((startColumn.getActiveNumber() + concurrentColumns - 1) > stopColumn.getActiveNumber()) { concurrentColumns = stopColumn.getActiveNumber() - startColumn.getActiveNumber() + 1; } // Populate the image data based on the output data type EncodingType outputDataType = pDescriptor->getDataType(); switch (outputDataType) { case INT1UBYTE: return populateImageData<unsigned char>(startRow, startColumn, concurrentRows, concurrentColumns); case INT1SBYTE: return populateImageData<signed char>(startRow, startColumn, concurrentRows, concurrentColumns); case INT2UBYTES: return populateImageData<unsigned short>(startRow, startColumn, concurrentRows, concurrentColumns); case INT2SBYTES: return populateImageData<signed short>(startRow, startColumn, concurrentRows, concurrentColumns); case INT4UBYTES: return populateImageData<unsigned int>(startRow, startColumn, concurrentRows, concurrentColumns); case INT4SBYTES: return populateImageData<signed int>(startRow, startColumn, concurrentRows, concurrentColumns); case FLT4BYTES: return populateImageData<float>(startRow, startColumn, concurrentRows, concurrentColumns); case FLT8BYTES: return populateImageData<double>(startRow, startColumn, concurrentRows, concurrentColumns); default: break; } return CachedPage::UnitPtr(); }
CachedPage::UnitPtr Jpeg2000Pager::populateImageData(const DimensionDescriptor& startRow, const DimensionDescriptor& startColumn, unsigned int concurrentRows, unsigned int concurrentColumns) const { VERIFYRV(startRow.isOnDiskNumberValid() == true, CachedPage::UnitPtr()); VERIFYRV(startColumn.isOnDiskNumberValid() == true, CachedPage::UnitPtr()); VERIFYRV(concurrentRows > 0, CachedPage::UnitPtr()); VERIFYRV(concurrentColumns > 0, CachedPage::UnitPtr()); // Get the rows, colums, and bands to load unsigned int onDiskStartRow = startRow.getOnDiskNumber(); unsigned int onDiskStopRow = onDiskStartRow + concurrentRows; unsigned int onDiskStartColumn = startColumn.getOnDiskNumber(); unsigned int onDiskStopColumn = onDiskStartColumn + concurrentColumns; const RasterElement* pRaster = getRasterElement(); VERIFYRV(pRaster != NULL, CachedPage::UnitPtr()); const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFYRV(pDescriptor != NULL, CachedPage::UnitPtr()); const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); VERIFYRV(pFileDescriptor != NULL, CachedPage::UnitPtr()); const std::vector<DimensionDescriptor>& allBands = pFileDescriptor->getBands(); if (allBands.empty() == true) { return CachedPage::UnitPtr(); } // Create the output data unsigned int numPixels = concurrentRows * concurrentColumns * allBands.size(); unsigned int numBytes = numPixels * getBytesPerBand(); if (numPixels > static_cast<unsigned int>(std::numeric_limits<int>::max())) // ArrayResource only allocates up // to INT_MAX number of values { return CachedPage::UnitPtr(); } ArrayResource<Out> pDestination(numPixels, true); char* pDest = reinterpret_cast<char*>(pDestination.get()); if (pDest == NULL) { return CachedPage::UnitPtr(); } memset(pDest, 0, numPixels); // Decode the image from the file, first trying the codestream format then the file format opj_image_t* pImage = decodeImage(onDiskStartRow, onDiskStartColumn, onDiskStopRow, onDiskStopColumn, Jpeg2000Utilities::J2K_CFMT); if (pImage == NULL) { pImage = decodeImage(onDiskStartRow, onDiskStartColumn, onDiskStopRow, onDiskStopColumn, Jpeg2000Utilities::JP2_CFMT); } if (pImage == NULL) { return CachedPage::UnitPtr(); } // Populate the output image data int bandFactor = 1; std::string filename = pRaster->getFilename(); if (filename.empty() == false) { QStringList parts = QString::fromStdString(filename).split('.'); foreach (QString part, parts) { bool error; EncodingType dataType = StringUtilities::fromXmlString<EncodingType>(part.toStdString(), &error); if (dataType.isValid() == true && error == false) { int currentBandFactor = Jpeg2000Utilities::get_num_bands(dataType); if (currentBandFactor > 0) { bandFactor = currentBandFactor; break; } } }
GcpList* RasterElementImporterShell::createGcpList() const { if (mpRasterElement == NULL) { return NULL; } const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(mpRasterElement->getDataDescriptor()); if (pDescriptor == NULL) { return NULL; } const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); if (pFileDescriptor == NULL) { return NULL; } const list<GcpPoint>& gcps = pFileDescriptor->getGcps(); if (gcps.empty() == true) { return NULL; } // Create the GCP list GcpList* pGcpList = static_cast<GcpList*>(mpModel->createElement("Corner Coordinates", "GcpList", mpRasterElement)); if (pGcpList != NULL) { unsigned int onDiskStartRow = 0; unsigned int onDiskStartColumn = 0; unsigned int numActiveRows = pDescriptor->getRowCount(); unsigned int numActiveColumns = pDescriptor->getColumnCount(); unsigned int numOnDiskRows = pFileDescriptor->getRowCount(); unsigned int numOnDiskColumns = pFileDescriptor->getColumnCount(); if ((numActiveRows != numOnDiskRows) || (numActiveColumns != numOnDiskColumns)) { const vector<DimensionDescriptor>& activeRows = pDescriptor->getRows(); if (activeRows.empty() == false) { DimensionDescriptor rowDim = activeRows.front(); if (rowDim.isOnDiskNumberValid()) { onDiskStartRow = rowDim.getOnDiskNumber(); } } const vector<DimensionDescriptor>& activeColumns = pDescriptor->getColumns(); if (activeColumns.empty() == false) { DimensionDescriptor columnDim = activeColumns.front(); if (columnDim.isOnDiskNumberValid()) { onDiskStartColumn = columnDim.getOnDiskNumber(); } } } // Add the GCPs to the GCP list list<GcpPoint> adjustedGcps; list<GcpPoint>::const_iterator iter; for (iter = gcps.begin(); iter != gcps.end(); ++iter) { GcpPoint gcp = *iter; gcp.mPixel.mX = gcp.mPixel.mX - onDiskStartColumn; gcp.mPixel.mY = gcp.mPixel.mY - onDiskStartRow; adjustedGcps.push_back(gcp); } pGcpList->addPoints(adjustedGcps); } return pGcpList; }