From 05a06793c7c413c5954f74229fe52cc7c19ad942 Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Mon, 27 Apr 2015 15:10:16 +0200
Subject: [PATCH] ENH: support OpenJPEG 2.0 and 2.1

---
 .../IO/IOJPEG2000/src/otbJPEG2000ImageIO.cxx  | 60 +++++++++++++++++--
 Modules/ThirdParty/OpenJPEG/CMakeLists.txt    | 12 ++++
 .../ThirdParty/OpenJPEG/src/otb_openjpeg.h.in | 29 +++++++++
 3 files changed, 95 insertions(+), 6 deletions(-)
 create mode 100644 Modules/ThirdParty/OpenJPEG/src/otb_openjpeg.h.in

diff --git a/Modules/IO/IOJPEG2000/src/otbJPEG2000ImageIO.cxx b/Modules/IO/IOJPEG2000/src/otbJPEG2000ImageIO.cxx
index 3343c3d942..12fb3dbb55 100644
--- a/Modules/IO/IOJPEG2000/src/otbJPEG2000ImageIO.cxx
+++ b/Modules/IO/IOJPEG2000/src/otbJPEG2000ImageIO.cxx
@@ -29,10 +29,7 @@
 
 #include <deque>
 
-extern "C"
-{
-#include "openjpeg.h"
-}
+#include "otb_openjpeg.h"
 
 #include "gdal.h"
 #include "gdaljp2metadata.h"
@@ -59,7 +56,15 @@ void OpjCodestreamDestroy(opj_codestream_info_v2_t * cstr)
 {
   opj_destroy_cstr_info(&cstr);
 }
-
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+void FileDestroy(FILE * file)
+{
+  if(file)
+    {
+    fclose(file);
+    }
+}
+#endif
 /**
 Divide an integer by a power of 2 and round upwards
 @return Returns a divided by 2^b
@@ -290,6 +295,9 @@ public:
 
 private:
   std::string m_FileName;
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+  boost::shared_ptr<FILE> m_File;
+#endif
   int Initialize();
 };
 
@@ -308,6 +316,15 @@ int JPEG2000InternalReader::Open(const char *filename, unsigned int resolution)
     return 0;
     }
 
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+  this->m_File  = boost::shared_ptr<FILE>(fopen(this->m_FileName.c_str(), "rb"),FileDestroy);
+  if (!this->m_File)
+    {
+    this->Clean();
+    return 0;
+    }
+#endif
+
   // Find the codec file format
 
   if (itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameLastExtension(m_FileName)) == ".j2k")
@@ -340,6 +357,10 @@ int JPEG2000InternalReader::Open(const char *filename, unsigned int resolution)
 
 void JPEG2000InternalReader::Clean()
 {
+  this->m_FileName.clear();
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+  this->m_File = boost::shared_ptr<FILE>();
+#endif
   this->m_XResolution.clear();
   this->m_YResolution.clear();
   this->m_Precision.clear();
@@ -361,7 +382,21 @@ void JPEG2000InternalReader::Clean()
 
 boost::shared_ptr<opj_image_t> JPEG2000InternalReader::DecodeTile(unsigned int tileIndex)
 {
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+  if (!this->m_File)
+    {
+    this->Clean();
+    return boost::shared_ptr<opj_image_t>();
+    }
 
+  // Creating the file stream
+  boost::shared_ptr<opj_stream_t> stream = boost::shared_ptr<opj_stream_t>(opj_stream_create_default_file_stream(this->m_File.get(), true),opj_stream_destroy);
+  if (!stream)
+    {
+    this->Clean();
+    return boost::shared_ptr<opj_image_t>();
+    }
+#else
   if (this->m_FileName.empty())
     {
     this->Clean();
@@ -375,6 +410,7 @@ boost::shared_ptr<opj_image_t> JPEG2000InternalReader::DecodeTile(unsigned int t
     this->Clean();
     return boost::shared_ptr<opj_image_t>();
     }
+#endif
 
   // Creating the codec
   boost::shared_ptr<opj_codec_t> codec = boost::shared_ptr<opj_codec_t>(opj_create_decompress(this->m_CodecFormat),opj_destroy_codec);
@@ -436,6 +472,18 @@ JPEG2000InternalReader::JPEG2000InternalReader()
 
 int JPEG2000InternalReader::Initialize()
 {
+#if defined(OTBOpenJPEG_VERSION_NUMBER) && OTBOpenJPEG_VERSION_NUMBER < 20100
+  if (this->m_File)
+    {
+    // Creating the file stream
+    boost::shared_ptr<opj_stream_t> stream = boost::shared_ptr<opj_stream_t>(opj_stream_create_default_file_stream(this->m_File.get(), true),opj_stream_destroy);
+    if (!stream)
+      {
+      std::cerr << "ERROR file stream creation" << std::endl;
+      this->Clean();
+      return 0;
+      }
+#else
   if (!m_FileName.empty())
     {
     // Creating the file stream
@@ -446,7 +494,7 @@ int JPEG2000InternalReader::Initialize()
       this->Clean();
       return 0;
       }
-
+#endif
     // Creating the codec
     boost::shared_ptr<opj_codec_t> codec = boost::shared_ptr<opj_codec_t>(opj_create_decompress(this->m_CodecFormat),opj_destroy_codec);
 
diff --git a/Modules/ThirdParty/OpenJPEG/CMakeLists.txt b/Modules/ThirdParty/OpenJPEG/CMakeLists.txt
index 1a91d19700..420a389287 100644
--- a/Modules/ThirdParty/OpenJPEG/CMakeLists.txt
+++ b/Modules/ThirdParty/OpenJPEG/CMakeLists.txt
@@ -2,7 +2,19 @@ project(OTBOpenJPEG)
   
   set(OTBOpenJPEG_SYSTEM_INCLUDE_DIRS ${OPENJPEG_INCLUDE_DIRS})
   set(OTBOpenJPEG_LIBRARIES "${OPENJPEG_LIBRARIES}")
+  set(OTBOpenJPEG_INCLUDE_DIRS ${OTBOpenJPEG_BINARY_DIR}/src)
   set(OTBOpenJPEG_EXPORT_CODE_BUILD "find_package(OpenJPEG REQUIRED HINTS ${OpenJPEG_DIR})")
   set(OTBOpenJPEG_EXPORT_CODE_INSTALL ${OTBOpenJPEG_EXPORT_CODE_BUILD})
   
+  if(OpenJPEG_FOUND)
+    math(EXPR OTBOpenJPEG_VERSION_NUMBER
+      "((${OPENJPEG_MAJOR_VERSION})*100+${OPENJPEG_MINOR_VERSION})*100+${OPENJPEG_BUILD_VERSION}")
+    configure_file( src/otb_openjpeg.h.in src/otb_openjpeg.h )
+  endif()
+
   otb_module_impl()
+
+install(FILES ${OTBOpenJPEG_BINARY_DIR}/src/otb_openjpeg.h
+  DESTINATION ${OTBOpenJPEG_INSTALL_INCLUDE_DIR}
+  COMPONENT Development
+  )
diff --git a/Modules/ThirdParty/OpenJPEG/src/otb_openjpeg.h.in b/Modules/ThirdParty/OpenJPEG/src/otb_openjpeg.h.in
new file mode 100644
index 0000000000..7150bb7eaa
--- /dev/null
+++ b/Modules/ThirdParty/OpenJPEG/src/otb_openjpeg.h.in
@@ -0,0 +1,29 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otb_openjpeg_h
+#define __otb_openjpeg_h
+
+/* different API between 2.0 and 2.1 */
+#define OTBOpenJPEG_VERSION_NUMBER @OTBOpenJPEG_VERSION_NUMBER@
+
+extern "C"
+{
+#include "openjpeg.h"
+}
+
+#endif
-- 
GitLab