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());
877 itkExceptionMacro(<<
"JPEG2000ImageIO : Bad alloc");
887 open = (*it)->m_IsOpen && open;
894 itkExceptionMacro(<<
"Cannot open file " << this->
m_FileName <<
"!");
901 itkExceptionMacro(<<
"Resolution not available in the file!");
906 if (tileList.empty())
914 itkExceptionMacro(<<
" IORegion does not correspond to any tile!");
918 std::vector<JPEG2000TileCache::CachedTileType> cachedTiles;
919 std::vector<JPEG2000TileCache::CachedTileType> toReadTiles;
921 for (std::vector<unsigned int>::iterator itTile = tileList.begin(); itTile < tileList.end(); ++itTile)
929 toReadTiles.push_back(currentTile);
933 cachedTiles.push_back(currentTile);
938 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = cachedTiles.begin(); itTile < cachedTiles.end(); ++itTile)
944 int nbTileToRemove =
static_cast<int>(toReadTiles.size())
946 if ( nbTileToRemove <= 0 )
950 for (
int itTileR = 0; itTileR < nbTileToRemove; ++itTileR)
956 if(!toReadTiles.empty())
959 if (nbThreads > toReadTiles.size())
961 nbThreads = toReadTiles.size();
968 str.
Tiles = &toReadTiles;
978 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
987 for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
1006 opj_image_t * currentTile =
static_cast<opj_image_t *
>(tile);
1010 itkExceptionMacro(<<
"Tile needed but not loaded.");
1018 unsigned int lWidthSrc;
1019 unsigned int lHeightDest;
1020 unsigned int lWidthDest;
1021 unsigned int lStartOffsetPxlDest;
1022 unsigned int lStartOffsetPxlSrc;
1024 ComputeOffsets(currentTile, this->
GetIORegion(), lWidthSrc, lHeightDest, lWidthDest, lStartOffsetPxlDest, lStartOffsetPxlSrc);
1030 char *p =
static_cast<char *
> (buffer);
1031 for (
unsigned int j = 0; j < lHeightDest; ++j)
1033 char* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1035 for (
unsigned int k = 0; k < lWidthDest; ++k)
1039 OPJ_INT32* data = currentTile->comps[itComp].data;
1040 *(current_dst_line++) = static_cast<char> (data[lStartOffsetPxlSrc + k + j * lWidthSrc]);
1048 unsigned char *p =
static_cast<unsigned char *
> (buffer);
1049 for (
unsigned int j = 0; j < lHeightDest; ++j)
1051 unsigned char* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1053 for (
unsigned int k = 0; k < lWidthDest; ++k)
1057 OPJ_INT32* data = currentTile->comps[itComp].data;
1058 unsigned char component_val = data[lStartOffsetPxlSrc + k + j * lWidthSrc] & 0xff;
1059 *(current_dst_line++) = static_cast<unsigned char> (component_val);
1067 short *p =
static_cast<short *
> (buffer);
1068 for (
unsigned int j = 0; j < lHeightDest; ++j)
1070 short* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1072 for (
unsigned int k = 0; k < lWidthDest; ++k)
1076 OPJ_INT32* data = currentTile->comps[itComp].data;
1077 *(current_dst_line++) = static_cast<short> (data[lStartOffsetPxlSrc + k + j * lWidthSrc]);
1085 unsigned short *p =
static_cast<unsigned short *
> (buffer);
1086 for (
unsigned int j = 0; j < lHeightDest; ++j)
1088 unsigned short* current_dst_line = p + (lStartOffsetPxlDest + j * lNbColumns) * this->
m_NumberOfComponents;
1090 for (
unsigned int k = 0; k < lWidthDest; ++k)
1094 OPJ_INT32* data = currentTile->comps[itComp].data;
1095 *(current_dst_line++) = static_cast<unsigned short> (data[lStartOffsetPxlSrc + k + j * lWidthSrc] & 0xffff);
1104 itkGenericExceptionMacro(<<
"This data type is not handled");
1112 unsigned int total, threadCount;
1121 std::vector<JPEG2000InternalReader *> readers = str->
Readers;
1122 std::vector<JPEG2000TileCache::CachedTileType> * tiles = str->
Tiles;
1124 total = std::min((
unsigned int)tiles->size(), threadCount);
1132 unsigned int tilesPerThread = tiles->size()/total;
1133 if(tilesPerThread == 0)
1138 for(
unsigned int i = threadId * tilesPerThread;
1139 i < tilesPerThread * (threadId+1);
1142 tiles->at(i).second = readers.at(threadId)->DecodeTile(tiles->at(i).first);
1145 if(!tiles->at(i).second)
1147 readers.at(threadId)->Clean();
1148 itkGenericExceptionMacro(
" otbopenjpeg failed to decode the desired tile "<<tiles->at(i).first <<
"!");
1150 otbMsgDevMacro(<<
" Tile " << tiles->at(i).first <<
" decoded by thread "<<threadId);
1153 unsigned int lastTile = threadCount*tilesPerThread + threadId;
1157 if(lastTile < tiles->size())
1159 tiles->at(lastTile).second = readers.at(threadId)->DecodeTile(tiles->at(lastTile).first);
1161 if(!tiles->at(lastTile).second)
1163 readers.at(threadId)->Clean();
1164 itkGenericExceptionMacro(
" otbopenjpeg failed to decode the desired tile "<<tiles->at(lastTile).first <<
"!");
1166 otbMsgDevMacro(<<
" Tile " << tiles->at(lastTile).first <<
" decoded by thread "<<threadId);
1190 if (lJP2MetadataReader.m_MetadataIsRead)
1195 if (lJP2MetadataReader.HaveGeoTransform())
1198 std::vector<double> geoTransform = lJP2MetadataReader.GetGeoTransform();
1211 m_Origin[1] = geoTransform[3];
1218 if (geoTransform[2] != 0 && geoTransform[4] != 0 )
1225 otbWarningMacro(<<
"JPEG2000 file has an incorrect geotransform (spacing = 0)!");
1233 if (lJP2MetadataReader.GetGCPCount() > 0)
1236 std::string gcpProjectionKey =
"UNKNOWN";
1239 int nbGCPs = lJP2MetadataReader.GetGCPCount();
1243 std::vector<GDAL_GCP> gcps = lJP2MetadataReader.GetGCPs();
1246 for (
int cpt = 0; cpt < nbGCPs; ++cpt)
1248 GDAL_GCP currentGCP = gcps[cpt];
1250 pOtbGCP.
m_Id = std::string(currentGCP.pszId);
1251 pOtbGCP.
m_Info = std::string(currentGCP.pszInfo);
1252 pOtbGCP.
m_GCPRow = currentGCP.dfGCPLine;
1253 pOtbGCP.
m_GCPCol = currentGCP.dfGCPPixel;
1254 pOtbGCP.
m_GCPX = currentGCP.dfGCPX;
1255 pOtbGCP.
m_GCPY = currentGCP.dfGCPY;
1256 pOtbGCP.
m_GCPZ = currentGCP.dfGCPZ;
1259 std::ostringstream lStream;
1261 key = lStream.str();
1263 itk::EncapsulateMetaData<OTB_GCP>(dict, key, pOtbGCP);
1268 char** papszGMLMetadata;
1269 papszGMLMetadata = lJP2MetadataReader.GetGMLMetadata();
1270 if (CSLCount(papszGMLMetadata) > 0)
1275 for (
int cpt = 0; papszGMLMetadata[cpt] !=
NULL; ++cpt)
1277 std::ostringstream lStream;
1279 key = lStream.str();
1281 itk::EncapsulateMetaData<std::string>(dict, key,
static_cast<std::string
> (papszGMLMetadata[cpt]));
1282 otbMsgDevMacro( << static_cast<std::string>(papszGMLMetadata[cpt]));
1288 if (lJP2MetadataReader.GetProjectionRef() && !std::string(lJP2MetadataReader.GetProjectionRef()).empty() )
1290 OGRSpatialReferenceH pSR = OSRNewSpatialReference(
NULL);
1292 const char * pszProjection =
NULL;
1293 pszProjection = lJP2MetadataReader.GetProjectionRef();
1295 if (OSRImportFromWkt(pSR, (
char **) (&pszProjection)) == OGRERR_NONE)
1297 char * pszPrettyWkt =
NULL;
1298 OSRExportToPrettyWkt(pSR, &pszPrettyWkt, FALSE);
1301 static_cast<std::string
>(pszPrettyWkt));
1303 CPLFree(pszPrettyWkt);
1308 static_cast<std::string
>(lJP2MetadataReader.GetProjectionRef()));
1319 otbMsgDevMacro( <<
"NO PROJECTION IN GML BOX => SENSOR MODEL " );
1323 lJP2MetadataReader.GetOriginFromGMLBox(
m_Origin);
1346 itkExceptionMacro(<<
"Cannot open file " << this->
m_FileName <<
"!");
1354 itkExceptionMacro(<<
"Cannot read this file because some JPEG2000 parameters are not supported!");
1369 bool success =
true;
1380 (*it)->m_IsOpen =
true;
1393 itkExceptionMacro(<<
"Cannot open this file with this resolution!");
1424 itkExceptionMacro(<<
"Image size is null.");
1448 else if (precision <= 16)
1516 std::vector<unsigned int> tileVector;
1532 unsigned int tilePosX0, tilePosX1;
1533 unsigned int tilePosY0, tilePosY1;
1535 for (
unsigned int itTileY = 0; itTileY < nbOfTileY; itTileY++)
1540 for (
unsigned int itTileX = 0; itTileX < nbOfTileX; itTileX++)
1545 if ( (tilePosX1 - tilePosX0) && (tilePosY1 - tilePosY0) &&
1546 (tilePosX1 > startX) && (tilePosX0 < endX ) &&
1547 (tilePosY1 > startY) && (tilePosY0 < endY ) )
1548 tileVector.push_back(itTileX + itTileY * nbOfTileX);
1561 unsigned int &l_width_src,
1562 unsigned int &l_height_dest,
1563 unsigned int &l_width_dest,
1564 unsigned int &l_start_offset_dest,
1565 unsigned int &l_start_offset_src
1569 unsigned int l_x0_src =
int_ceildivpow2(currentTile->x0, currentTile->comps->factor);
1570 unsigned int l_y0_src =
int_ceildivpow2(currentTile->y0, currentTile->comps->factor);
1571 unsigned int l_x1_src =
int_ceildivpow2(currentTile->x1, currentTile->comps->factor);
1572 unsigned int l_y1_src =
int_ceildivpow2(currentTile->y1, currentTile->comps->factor);
1575 l_width_src = l_x1_src - l_x0_src;
1576 unsigned int l_height_src = l_y1_src - l_y0_src;
1579 unsigned int l_x0_dest = ioRegion.
GetIndex()[0];
1580 unsigned int l_x1_dest = ioRegion.
GetIndex()[0] + ioRegion.
GetSize()[0];
1581 unsigned int l_y0_dest = ioRegion.
GetIndex()[1];
1582 unsigned int l_y1_dest = ioRegion.
GetIndex()[1] + ioRegion.
GetSize()[1];
1584 unsigned int l_start_x_dest, l_start_y_dest;
1585 unsigned int l_offset_x0_src, l_offset_y0_src;
1596 if (l_x0_dest < l_x0_src)
1598 l_start_x_dest = l_x0_src - l_x0_dest;
1599 l_offset_x0_src = 0;
1601 if (l_x1_dest >= l_x1_src)
1603 l_width_dest = l_width_src;
1607 l_width_dest = l_x1_dest - l_x0_src;
1613 l_offset_x0_src = l_x0_dest - l_x0_src;
1615 if (l_x1_dest >= l_x1_src)
1617 l_width_dest = l_width_src - l_offset_x0_src;
1621 l_width_dest = l_x1_dest - l_x0_dest;
1625 if (l_y0_dest < l_y0_src)
1627 l_start_y_dest = l_y0_src - l_y0_dest;
1628 l_offset_y0_src = 0;
1630 if (l_y1_dest >= l_y1_src)
1632 l_height_dest = l_height_src;
1636 l_height_dest = l_y1_dest - l_y0_src;
1642 l_offset_y0_src = l_y0_dest - l_y0_src;
1644 if (l_y1_dest >= l_y1_src)
1646 l_height_dest = l_height_src - l_offset_y0_src;
1650 l_height_dest = l_y1_dest - l_y0_dest;
1656 l_start_offset_src = l_offset_x0_src + l_offset_y0_src * l_width_src;
1659 l_start_offset_dest = l_start_x_dest + l_start_y_dest * (l_x1_dest - l_x0_dest);
1689 itkExceptionMacro(<<
"A FileName must be specified.");
1693 itkExceptionMacro(<<
"The file " <<
m_FileName.c_str() <<
" is not defined as a JPEG2000 file");