//
// fiwrap.cpp - wrapper for FreeImage routines, which we might want to use.
//
// Written by John A deLaubenfels, https://www.adaptune.com/steg.htm .
// Permission granted to use freely in any non-fraudulent way.
//
//
//
//
//
//
//


#ifdef NEED_PCH
   #include "pch.h"
#else
   #include "stdafx.h"
#endif // !NEED_PCH


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "globs.h"
#include "fiwrap.h"

#ifdef USE_FI
#include "FreeImage.h"
#endif // USE_FI


#ifdef USE_FI

#pragma warning( disable : 4996 )

//
//
//
//
//
//
//
// qxtestFIopen()
//

int testFIopen(const char *cFile) {

   // sanity check(s):
   if(cFile == NULL) return NADA;

   FREE_IMAGE_FORMAT fif = FIF_BMP;

   FIBITMAP *dib = FreeImage_Load(fif, cFile, BMP_DEFAULT);

   // sanity check:
   if(dib == NULL) return NADA;

   char *pBodyOut = new char[strlen(cFile) + 8];
   char *pDottOut = new char[strlen(cFile) + 8];
   char *pExttOut = new char[strlen(cFile) + 8];
   char *pNewfOut = new char[strlen(cFile) + 8];

   break_file_name(cFile, pBodyOut, pDottOut, pExttOut);
   // case_change(pExttOut, CASE_LOWER);

   sprintf(pNewfOut, "%s%s%s", pBodyOut, pDottOut, "jpg");
   // fp_db2 = fopen(pNewfOut, "w");

   // write the file back out, in .jpg format:
   fif = FIF_JPEG;

   // wait a second, what am I, crazy???  Let's use "blah.jpg":
   sprintf(pNewfOut, "blah.jpg");

   BOOL bRes = FreeImage_Save(fif, dib, pNewfOut, JPEG_DEFAULT);

   // let's try some other jpg stuffs:
   bRes = FreeImage_Save(fif, dib, "blahfast.jpg", JPEG_FAST);
   bRes = FreeImage_Save(fif, dib, "blahaccurate.jpg", JPEG_ACCURATE);
   bRes = FreeImage_Save(fif, dib, "blahsuperb.jpg", JPEG_QUALITYSUPERB);
   bRes = FreeImage_Save(fif, dib, "blahgood.jpg", JPEG_QUALITYGOOD);
   bRes = FreeImage_Save(fif, dib, "blahnormal.jpg", JPEG_QUALITYNORMAL);
   bRes = FreeImage_Save(fif, dib, "blahaverage.jpg", JPEG_QUALITYAVERAGE);
   bRes = FreeImage_Save(fif, dib, "blahbad.jpg", JPEG_QUALITYBAD);


   // clean up:
   delete pBodyOut; pBodyOut=NULL;
   delete pDottOut; pDottOut=NULL;
   delete pExttOut; pExttOut=NULL;
   delete pNewfOut; pNewfOut=NULL;

   // is this the right call?  It's in one of the examples:
   FreeImage_Unload(dib); dib=NULL;

   return 0;
} // end of testFIopen()...




//
// new 07-20-25
//
//
//
//
//
// qxsomethingToBmp()
//

int somethingToBmp(FREE_IMAGE_FORMAT FIFormat, int FIQuality, const char *cSom, const char *cBmp, int force) {

   // sanity check(s):
   if(cSom == NULL) return NADA;
   if(cBmp == NULL) return NADA;

   qprintf(fp_dbg, "This is somethingToBmp() with cSom \"%s\", cBmp \"%s\".\n", cSom, cBmp);

   if(file_t(cSom) < 0) return NADA;   // input file does not exist...
   if(file_t(cBmp) >= 0) {
      // output file already exists!
      if(!force) {
         qprintf(fp_dbg, "somethingToBmp() aborting: file %s already exists!\n", cBmp);
         return NADA;
      } // if(!force)

      // try to remove existing output file:
      remove(cBmp);
      if(file_t(cBmp) >= 0) {
         // failed to remove!
         qprintf(fp_dbg, "somethingToBmp() aborting: failed to kill old file %s!\n", cBmp);
         return NADA;
      } // if(file_t(cBmp) >= 0)
   } // if(file_t(cBmp) >= 0)

   qprintf(fp_dbg, "The input file exists, and the output file does not.\n");

   FREE_IMAGE_FORMAT fif = FIFormat;

   FIBITMAP *dib = FreeImage_Load(fif, cSom, FIQuality);
   // SmartParr<FIBITMAP> smaDib(dib);   // barfs at runtime.

   // qprintf(fp_dbg, "dib = %p.\n", dib);

   // sanity check:
   if(dib == NULL) return NADA;

   // save the .bmp:
   fif = FIF_BMP;
   BOOL bRes = FreeImage_Save(fif, dib, cBmp, BMP_DEFAULT);

   FreeImage_Unload(dib);   // xptl 11-11-23

   // qprintf(fp_dbg, "bRes = %d.\n", bRes);

   return (int)bRes;
} // end of somethingToBmp()...





//
// new 02-05-04
//
//
//
//
// 11-11-23: attempt to fix memory leak.
// 07-20-25: call new inner function.
//
// qxjpgToBmp()
//

int jpgToBmp(const char *cJpg, const char *cBmp, int force) {

   int iRet = somethingToBmp(FIF_JPEG, 0, cJpg, cBmp, force);
   return iRet;

#ifdef REPLACED_D
   // sanity check(s):
   if(cJpg == NULL) return NADA;
   if(cBmp == NULL) return NADA;

   qprintf(fp_dbg, "This is jpgToBmp() with cJpg \"%s\", cBmp \"%s\".\n", cJpg, cBmp);

   if(file_t(cJpg) < 0) return NADA;   // input file does not exist...
   if(file_t(cBmp) >= 0) {
      // output file already exists!
      if(!force) {
         qprintf(fp_dbg, "jpgToBmp() aborting: file %s already exists!\n", cBmp);
         return NADA;
      } // if(!force)

      // try to remove existing output file:
      remove(cBmp);
      if(file_t(cBmp) >= 0) {
         // failed to remove!
         qprintf(fp_dbg, "jpgToBmp() aborting: failed to kill old file %s!\n", cBmp);
         return NADA;
      } // if(file_t(cBmp) >= 0)
   } // if(file_t(cBmp) >= 0)

   qprintf(fp_dbg, "The input file exists, and the output file does not.\n");

   FREE_IMAGE_FORMAT fif = FIF_JPEG;

   FIBITMAP *dib = FreeImage_Load(fif, cJpg, JPEG_DEFAULT);
   // SmartParr<FIBITMAP> smaDib(dib);   // barfs at runtime.

   // qprintf(fp_dbg, "dib = %p.\n", dib);

   // sanity check:
   if(dib == NULL) return NADA;

   // save the .bmp:
   fif = FIF_BMP;
   BOOL bRes = FreeImage_Save(fif, dib, cBmp, BMP_DEFAULT);

   FreeImage_Unload(dib);   // xptl 11-11-23

   // qprintf(fp_dbg, "bRes = %d.\n", bRes);

   return (int)bRes;
#endif // REPLACED_D
} // end of jpgToBmp()...





//
// new 07-20-25
//
//
//
//
//
//
//
// qxpngToBmp()
//

int pngToBmp(const char *cPng, const char *cBmp, int force) {

   int iRet = somethingToBmp(FIF_PNG, 0, cPng, cBmp, force);
   return iRet;

} // int pngToBmp(const char *cPng, const char *cBmp, int force)




//
// new 07-20-25
//
//
//
//
//
//
//
// qxbmpToSomething()
//

int bmpToSomething(FREE_IMAGE_FORMAT FIFormat, int FIQuality, const char *cBmp, const char *cSom, int force) {

   // sanity check(s):
   if(cBmp == NULL) return NADA;
   if(cSom == NULL) return NADA;

   qprintf(fp_dbg, "This is bmpToSomething() with cBmp \"%s\", cSom \"%s\", force %d, quality 0x%x.\n", cBmp, cSom, force, FIQuality);

   if(file_t(cBmp) < 0) return NADA;   // input file does not exist...
   if(file_t(cSom) >= 0) {
      // output file already exists!
      if(!force) {
         qprintf(fp_dbg, "bmpToSomething() aborting: file %s already exists!\n", cSom);
         return NADA;
      } // if(!force)

      // try to remove existing output file:
      remove(cSom);
      if(file_t(cSom) >= 0) {
         // failed to remove!
         qprintf(fp_dbg, "bmpToSomething() aborting: failed to kill old file %s!\n", cSom);
         return NADA;
      } // if(file_t(cSom) >= 0)
   } // if(file_t(cSom) >= 0)

   FREE_IMAGE_FORMAT fif = FIF_BMP;

   FIBITMAP *dib = FreeImage_Load(fif, cBmp, BMP_DEFAULT);

   // sanity check:
   if(dib == NULL) return NADA;

   // save the .something:
   fif = FIFormat;

   BOOL bRes = FreeImage_Save(fif, dib, cSom, FIQuality);

   FreeImage_Unload(dib);   // xptl 11-11-23

   return (int)bRes;
} // end of bmpToSomething()...






//
// new 02-05-04
//
//
//
//
// 12-22-06 (jdl): quality (defaults to 0, which is JPEG_DEFAULT).
// 11-11-23: attempt to fix memory leak.
// 07-20-25: call new inner function.
//
// qxbmpToJpg()
//

int bmpToJpg(const char *cBmp, const char *cJpg, int force, int quality) {

   int iRet = bmpToSomething(FIF_JPEG, quality, cBmp, cJpg, force);
   return iRet;


#ifdef REPLACED_D
   // sanity check(s):
   if(cBmp == NULL) return NADA;
   if(cJpg == NULL) return NADA;

   qprintf(fp_dbg, "This is bmpToJpg() with cBmp \"%s\", cJpg \"%s\", force %d, quality 0x%x.\n", cBmp, cJpg, force, quality);

   if(file_t(cBmp) < 0) return NADA;   // input file does not exist...
   if(file_t(cJpg) >= 0) {
      // output file already exists!
      if(!force) {
         qprintf(fp_dbg, "bmpToJpg() aborting: file %s already exists!\n", cJpg);
         return NADA;
      } // if(!force)

      // try to remove existing output file:
      remove(cJpg);
      if(file_t(cJpg) >= 0) {
         // failed to remove!
         qprintf(fp_dbg, "bmpToJpg() aborting: failed to kill old file %s!\n", cJpg);
         return NADA;
      } // if(file_t(cJpg) >= 0)
   } // if(file_t(cJpg) >= 0)

   FREE_IMAGE_FORMAT fif = FIF_BMP;

   FIBITMAP *dib = FreeImage_Load(fif, cBmp, BMP_DEFAULT);

   // sanity check:
   if(dib == NULL) return NADA;

   // save the .jpg:
   fif = FIF_JPEG;
   // BOOL bRes = FreeImage_Save(fif, dib, cJpg, JPEG_DEFAULT);
   BOOL bRes = FreeImage_Save(fif, dib, cJpg, quality);                 // 12-22-06 (jdl)

   FreeImage_Unload(dib);   // xptl 11-11-23

   return (int)bRes;
#endif // REPLACED_D
} // end of bmpToJpg()...



//
// new 07-20-25
//
//
//
//
//
//
//
//
// qxbmpToPng()
//

int bmpToPng(const char *cBmp, const char *cPng, int force, int quality) {

   int iRet = bmpToSomething(FIF_PNG, quality, cBmp, cPng, force);

   return iRet;
} // int bmpToPng(const char *cBmp, const char *cPng, int force, int quality)








#endif // USE_FI


