40 #include "gdaljp2metadata.h"
41 #include "cpl_string.h"
42 #include "ogr_spatialref.h"
43 #include "ogr_srs_api.h"
45 #include "itksys/SystemTools.hxx"
55 return (a + (1 << b) - 1) >> b;
59 return (a + (1 << b) - 1) >> b;
96 unsigned int &l_width_src,
97 unsigned int &l_height_dest,
98 unsigned int &l_width_dest,
99 unsigned int &l_start_offset_dest,
100 unsigned int &l_start_offset_src);
123 std::vector<double> geoTransform;
124 for (
unsigned int i = 0; i< 6; i++ )
141 std::vector<GDAL_GCP> gcps;
143 for (
int i = 0; i< nbGCP; i++ )
181 std::string gmlString =
static_cast<std::string
> (
m_JP2Metadata.papszGMLMetadata[0]);
182 gmlString.erase(0,18);
186 doc.Parse(gmlString.c_str());
188 TiXmlHandle docHandle( &doc );
189 TiXmlElement* originTag = docHandle.FirstChild(
"gml:FeatureCollection" )
190 .FirstChild(
"gml:featureMember" )
191 .FirstChild(
"gml:FeatureCollection" )
192 .FirstChild(
"gml:featureMember" )
193 .FirstChild(
"gml:GridCoverage" )
194 .FirstChild(
"gml:gridDomain")
195 .FirstChild(
"gml:Grid" )
196 .FirstChild(
"gml:limits" )
197 .FirstChild(
"gml:GridEnvelope" )
198 .FirstChild(
"gml:low").ToElement();
201 otbMsgDevMacro( <<
"\t Origin (" << originTag->Value() <<
" tag)= "<< originTag->GetText());
205 otbMsgDevMacro( <<
"Didn't find the GML element which indicate the origin!" );
209 std::vector<itksys::String> originValues;
210 originValues = itksys::SystemTools::SplitString(originTag->GetText(),
' ',
false);
212 std::istringstream ss0 (originValues[0]);
213 std::istringstream ss1 (originValues[1]);
219 otbMsgDevMacro( <<
"\t Origin from GML box: " << origin[0] <<
", " << origin[1] );
238 opj_image_t *
DecodeTile(
unsigned int tileIndex);
246 int Open(
const char *filename,
unsigned int resolution);
292 this->
m_File = fopen(filename,
"rb");
299 std::string lFileName(filename);
334 otbopenjpeg_opj_image_destroy(this->
m_Image);
341 otbopenjpeg_opj_stream_destroy(this->
m_Stream);
355 otbopenjpeg_opj_destroy_codec(this->
m_Codec);
362 otbopenjpeg_opj_destroy_cstr_info_v2(&(this->
m_CstrInfo));
386 opj_image_t * image = otbopenjpeg_opj_image_create0();
387 otbopenjpeg_opj_copy_image_header(
m_Image, image);
389 bool success = otbopenjpeg_opj_get_decoded_tile(
m_Codec,
m_Stream, image, tileIndex);
425 this->
m_Stream = otbopenjpeg_opj_stream_create_default_file_stream(this->
m_File,
true);
441 opj_dparameters_t parameters;
442 otbopenjpeg_opj_set_default_decoder_parameters(¶meters);
445 otbMsgDevMacro( <<
"Initialize decoder with cp_reduce = " << parameters.cp_reduce);
465 std::cerr <<
"ERROR while get codestream info" << std::endl;
475 otbMsgDevMacro(<<
"JPEG2000InternalReader dimension (after reading header) = " << this->
m_Image->comps->w <<
" x "
476 << this->m_Image->comps->h );
485 for (
unsigned int itComp = 0; itComp < this->
m_NbOfComponent; itComp++)
495 unsigned int numResAvailable = this->
m_CstrInfo->m_default_tile_info.tccp_info[0].numresolutions;
496 for (
unsigned int itRes = 0; itRes < numResAvailable; itRes++)
519 for(
unsigned int itComp = 0; itComp < this->
m_NbOfComponent - 1; itComp++)
551 opj_image_t *
GetTile(
unsigned int tileIndex);
554 void AddTile(
unsigned int tileIndex, opj_image_t * tileData);
563 void Initialize(
unsigned int originalWidthTile,
unsigned int originalHeightTile,
564 unsigned int nbComponent,
565 unsigned int precision,
566 unsigned int resolution)
604 return static_cast<unsigned int>(
m_Cache.size());
616 unsigned int nbComponent,
617 unsigned int precision,
618 unsigned int resolution);
632 unsigned int nbComponent,
633 unsigned int precision,
634 unsigned int resolution)
639 / vcl_pow(2, 2*static_cast<double>(resolution) );
644 <<
" bytes so we don't used the cache");
652 for(TileCacheType::iterator it =
m_Cache.begin();
658 if (erasedTile.second)
660 otbopenjpeg_opj_image_destroy(erasedTile.second);
662 erasedTile.second =
NULL;
675 for(TileCacheType::iterator it =
m_Cache.begin();
678 if(it->first == tileIndex)
694 if (erasedTile.second)
696 otbopenjpeg_opj_image_destroy(erasedTile.second);
698 erasedTile.second =
NULL;
706 for(TileCacheType::const_iterator it =
m_Cache.begin();
709 if(it->first == tileIndex)
773 if (filename ==
NULL)
775 itkDebugMacro(<<
"No filename specified.");
820 std::vector<JPEG2000InternalReader *>
Readers;
821 std::vector<JPEG2000TileCache::CachedTileType> *
Tiles;
836 for (std::vector<unsigned int>::iterator itRes = res.begin(); itRes < res.end(); itRes++)
839 std::ostringstream oss;
847 oss <<
"Resolution: " << *itRes <<
" (Image [w x h]: " << w <<
"x" << h <<
", Tile [w x h]: " << tw <<
"x" << th <<
")";
849 desc.push_back(oss.str());
868 std::vector<unsigned int> tempResList = this->
m_InternalReaders[0]->GetAvailableResolutions();
870 if (tempResList.empty())
872 itkExceptionMacro(<<
"Available resolutions in JPEG2000 is empty");
875 return tempResList.size() - 1;
888 itkExceptionMacro(<<
"JPEG2000ImageIO : Bad alloc");
898 open = (*it)->m_IsOpen && open;
905 itkExceptionMacro(<<
"Cannot open file " << this->
m_FileName <<
"!");
912 itkExceptionMacro(<<
"Resolution not available in the file!");
917 if (tileList.empty())
925 itkExceptionMacro(<<
" IORegion does not correspond to any tile!");
929 std::vector<JPEG2000TileCache::CachedTileType> cachedTiles;
930 std::vector<JPEG2000TileCache::CachedTileType> toReadTiles;
932 for (std::vector<unsigned int>::iterator itTile = tileList.begin(); itTile < tileList.end(); ++itTile)
940 toReadTiles.push_back(currentTile);
944 cachedTiles.push_back(currentTile);
949 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = cachedTiles.begin(); itTile < cachedTiles.end(); ++itTile)
955 int nbTileToRemove =
static_cast<int>(toReadTiles.size())
957 if ( nbTileToRemove <= 0 )
961 for (
int itTileR = 0; itTileR < nbTileToRemove; ++itTileR)
967 if(!toReadTiles.empty())
970 if (nbThreads > toReadTiles.size())
972 nbThreads = toReadTiles.size();
979 str.
Tiles = &toReadTiles;
989 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
998 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
1017 opj_image_t * currentTile =
static_cast<opj_image_t *
>(tile);
1021 itkExceptionMacro(<<
"Tile needed but not loaded.");
1029 unsigned int lWidthSrc;
1030 unsigned int lHeightDest;
1031 unsigned int lWidthDest;
1032 unsigned int lStartOffsetPxlDest;
1033 unsigned int lStartOffsetPxlSrc;
1035 ComputeOffsets(currentTile, this->
GetIORegion(), lWidthSrc, lHeightDest, lWidthDest, lStartOffsetPxlDest, lStartOffsetPxlSrc);
1041 char *p =
static_cast<char *
> (buffer);
1042 for (
unsigned int j = 0; j < lHeightDest; ++j)
1044 char* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1046 for (
unsigned int k = 0; k < lWidthDest; ++k)
1050 OPJ_INT32* data = currentTile->comps[itComp].data;
1051 *(current_dst_line++) = static_cast<char> (data[lStartOffsetPxlSrc + k + j * lWidthSrc]);
1059 unsigned char *p =
static_cast<unsigned char *
> (buffer);
1060 for (
unsigned int j = 0; j < lHeightDest; ++j)
1062 unsigned char* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1064 for (
unsigned int k = 0; k < lWidthDest; ++k)
1068 OPJ_INT32* data = currentTile->comps[itComp].data;
1069 unsigned char component_val = data[lStartOffsetPxlSrc + k + j * lWidthSrc] & 0xff;
1070 *(current_dst_line++) = static_cast<unsigned char> (component_val);
1078 short *p =
static_cast<short *
> (buffer);
1079 for (
unsigned int j = 0; j < lHeightDest; ++j)
1081 short* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1083 for (
unsigned int k = 0; k < lWidthDest; ++k)
1087 OPJ_INT32* data = currentTile->comps[itComp].data;
1088 *(current_dst_line++) = static_cast<short> (data[lStartOffsetPxlSrc + k + j * lWidthSrc]);
1096 unsigned short *p =
static_cast<unsigned short *
> (buffer);
1097 for (
unsigned int j = 0; j < lHeightDest; ++j)
1099 unsigned short* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1101 for (
unsigned int k = 0; k < lWidthDest; ++k)
1105 OPJ_INT32* data = currentTile->comps[itComp].data;
1106 *(current_dst_line++) = static_cast<unsigned short> (data[lStartOffsetPxlSrc + k + j * lWidthSrc] & 0xffff);
1115 itkGenericExceptionMacro(<<
"This data type is not handled");
1123 unsigned int total, threadCount;
1132 std::vector<JPEG2000InternalReader *> readers = str->
Readers;
1133 std::vector<JPEG2000TileCache::CachedTileType> * tiles = str->
Tiles;
1135 total = std::min((
unsigned int)tiles->size(), threadCount);
1143 unsigned int tilesPerThread = tiles->size()/total;
1144 if(tilesPerThread == 0)
1149 for(
unsigned int i = threadId * tilesPerThread;
1150 i < tilesPerThread * (threadId+1);
1153 tiles->at(i).second = readers.at(threadId)->DecodeTile(tiles->at(i).first);
1156 if(!tiles->at(i).second)
1158 readers.at(threadId)->Clean();
1159 itkGenericExceptionMacro(
" otbopenjpeg failed to decode the desired tile "<<tiles->at(i).first <<
"!");
1161 otbMsgDevMacro(<<
" Tile " << tiles->at(i).first <<
" decoded by thread "<<threadId);
1164 unsigned int lastTile = threadCount*tilesPerThread + threadId;
1168 if(lastTile < tiles->size())
1170 tiles->at(lastTile).second = readers.at(threadId)->DecodeTile(tiles->at(lastTile).first);
1172 if(!tiles->at(lastTile).second)
1174 readers.at(threadId)->Clean();
1175 itkGenericExceptionMacro(
" otbopenjpeg failed to decode the desired tile "<<tiles->at(lastTile).first <<
"!");
1177 otbMsgDevMacro(<<
" Tile " << tiles->at(lastTile).first <<
" decoded by thread "<<threadId);
1201 if (lJP2MetadataReader.m_MetadataIsRead)
1206 if (lJP2MetadataReader.HaveGeoTransform())
1209 std::vector<double> geoTransform = lJP2MetadataReader.GetGeoTransform();
1222 m_Origin[1] = geoTransform[3];
1229 if (geoTransform[2] != 0 && geoTransform[4] != 0 )
1236 otbWarningMacro(<<
"JPEG2000 file has an incorrect geotransform (spacing = 0)!");
1244 if (lJP2MetadataReader.GetGCPCount() > 0)
1247 std::string gcpProjectionKey =
"UNKNOWN";
1250 int nbGCPs = lJP2MetadataReader.GetGCPCount();
1254 std::vector<GDAL_GCP> gcps = lJP2MetadataReader.GetGCPs();
1257 for (
int cpt = 0; cpt < nbGCPs; ++cpt)
1259 GDAL_GCP currentGCP = gcps[cpt];
1261 pOtbGCP.
m_Id = std::string(currentGCP.pszId);
1262 pOtbGCP.
m_Info = std::string(currentGCP.pszInfo);
1263 pOtbGCP.
m_GCPRow = currentGCP.dfGCPLine;
1264 pOtbGCP.
m_GCPCol = currentGCP.dfGCPPixel;
1265 pOtbGCP.
m_GCPX = currentGCP.dfGCPX;
1266 pOtbGCP.
m_GCPY = currentGCP.dfGCPY;
1267 pOtbGCP.
m_GCPZ = currentGCP.dfGCPZ;
1270 std::ostringstream lStream;
1272 key = lStream.str();
1274 itk::EncapsulateMetaData<OTB_GCP>(dict, key, pOtbGCP);
1279 char** papszGMLMetadata;
1280 papszGMLMetadata = lJP2MetadataReader.GetGMLMetadata();
1281 if (CSLCount(papszGMLMetadata) > 0)
1286 for (
int cpt = 0; papszGMLMetadata[cpt] !=
NULL; ++cpt)
1288 std::ostringstream lStream;
1290 key = lStream.str();
1292 itk::EncapsulateMetaData<std::string>(dict, key,
static_cast<std::string
> (papszGMLMetadata[cpt]));
1293 otbMsgDevMacro( << static_cast<std::string>(papszGMLMetadata[cpt]));
1299 if (lJP2MetadataReader.GetProjectionRef() && !std::string(lJP2MetadataReader.GetProjectionRef()).empty() )
1301 OGRSpatialReferenceH pSR = OSRNewSpatialReference(
NULL);
1303 const char * pszProjection =
NULL;
1304 pszProjection = lJP2MetadataReader.GetProjectionRef();
1306 if (OSRImportFromWkt(pSR, (
char **) (&pszProjection)) == OGRERR_NONE)
1308 char * pszPrettyWkt =
NULL;
1309 OSRExportToPrettyWkt(pSR, &pszPrettyWkt, FALSE);
1312 static_cast<std::string
>(pszPrettyWkt));
1314 CPLFree(pszPrettyWkt);
1319 static_cast<std::string
>(lJP2MetadataReader.GetProjectionRef()));
1330 otbMsgDevMacro( <<
"NO PROJECTION IN GML BOX => SENSOR MODEL " );
1334 lJP2MetadataReader.GetOriginFromGMLBox(
m_Origin);
1357 itkExceptionMacro(<<
"Cannot open file " << this->
m_FileName <<
"!");
1365 itkExceptionMacro(<<
"Cannot read this file because some JPEG2000 parameters are not supported!");
1380 bool success =
true;
1391 (*it)->m_IsOpen =
true;
1404 itkExceptionMacro(<<
"Cannot open this file with this resolution!");
1435 itkExceptionMacro(<<
"Image size is null.");
1459 else if (precision <= 16)
1527 std::vector<unsigned int> tileVector;
1543 unsigned int tilePosX0, tilePosX1;
1544 unsigned int tilePosY0, tilePosY1;
1546 for (
unsigned int itTileY = 0; itTileY < nbOfTileY; itTileY++)
1551 for (
unsigned int itTileX = 0; itTileX < nbOfTileX; itTileX++)
1556 if ( (tilePosX1 - tilePosX0) && (tilePosY1 - tilePosY0) &&
1557 (tilePosX1 > startX) && (tilePosX0 < endX ) &&
1558 (tilePosY1 > startY) && (tilePosY0 < endY ) )
1559 tileVector.push_back(itTileX + itTileY * nbOfTileX);
1572 unsigned int &l_width_src,
1573 unsigned int &l_height_dest,
1574 unsigned int &l_width_dest,
1575 unsigned int &l_start_offset_dest,
1576 unsigned int &l_start_offset_src
1580 unsigned int l_x0_src =
int_ceildivpow2(currentTile->x0, currentTile->comps->factor);
1581 unsigned int l_y0_src =
int_ceildivpow2(currentTile->y0, currentTile->comps->factor);
1582 unsigned int l_x1_src =
int_ceildivpow2(currentTile->x1, currentTile->comps->factor);
1583 unsigned int l_y1_src =
int_ceildivpow2(currentTile->y1, currentTile->comps->factor);
1586 l_width_src = l_x1_src - l_x0_src;
1587 unsigned int l_height_src = l_y1_src - l_y0_src;
1590 unsigned int l_x0_dest = ioRegion.
GetIndex()[0];
1591 unsigned int l_x1_dest = ioRegion.
GetIndex()[0] + ioRegion.
GetSize()[0];
1592 unsigned int l_y0_dest = ioRegion.
GetIndex()[1];
1593 unsigned int l_y1_dest = ioRegion.
GetIndex()[1] + ioRegion.
GetSize()[1];
1595 unsigned int l_start_x_dest, l_start_y_dest;
1596 unsigned int l_offset_x0_src, l_offset_y0_src;
1607 if (l_x0_dest < l_x0_src)
1609 l_start_x_dest = l_x0_src - l_x0_dest;
1610 l_offset_x0_src = 0;
1612 if (l_x1_dest >= l_x1_src)
1614 l_width_dest = l_width_src;
1618 l_width_dest = l_x1_dest - l_x0_src;
1624 l_offset_x0_src = l_x0_dest - l_x0_src;
1626 if (l_x1_dest >= l_x1_src)
1628 l_width_dest = l_width_src - l_offset_x0_src;
1632 l_width_dest = l_x1_dest - l_x0_dest;
1636 if (l_y0_dest < l_y0_src)
1638 l_start_y_dest = l_y0_src - l_y0_dest;
1639 l_offset_y0_src = 0;
1641 if (l_y1_dest >= l_y1_src)
1643 l_height_dest = l_height_src;
1647 l_height_dest = l_y1_dest - l_y0_src;
1653 l_offset_y0_src = l_y0_dest - l_y0_src;
1655 if (l_y1_dest >= l_y1_src)
1657 l_height_dest = l_height_src - l_offset_y0_src;
1661 l_height_dest = l_y1_dest - l_y0_dest;
1667 l_start_offset_src = l_offset_x0_src + l_offset_y0_src * l_width_src;
1670 l_start_offset_dest = l_start_x_dest + l_start_y_dest * (l_x1_dest - l_x0_dest);
1700 itkExceptionMacro(<<
"A FileName must be specified.");
1704 itkExceptionMacro(<<
"The file " <<
m_FileName.c_str() <<
" is not defined as a JPEG2000 file");