//---------------------------------------------------------------------------


#include <vcl.h>
#pragma hdrstop

#include "wsq_demo_main_form.h"



//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{


   hBitmap = (HBITMAP)NULL;
   comment_text = (char*) NULL; // It is important to initialize to NULL to avoid crashing
   comment_text2 = (char*) NULL; // It is important to initialize to NULL to avoid crashing


   // returns a handle to the DLL, otherwise NULL
   hWSQ_library = LoadLibraryW(L"WSQ_library.dll");

   if (hWSQ_library == NULL)
   {Application->MessageBox( L"Error: WSQ_library.dll not found", L"Error", MB_OK);}


   pRegisterWSQ = (RegisterWSQ) GetProcAddress(hWSQ_library, "_RegisterWSQ");
   pCreateBMPFromFile = (CreateBMPFromFile) GetProcAddress(hWSQ_library, "_CreateBMPFromFile");
   pSaveBMPToFile = (SaveBMPToFile) GetProcAddress(hWSQ_library, "_SaveBMPToFile");
   pCreateBMPFromWSQByteArray = (CreateBMPFromWSQByteArray) GetProcAddress(hWSQ_library, "_CreateBMPFromWSQByteArray");
   pSaveWSQByteArrayToImageFile = (SaveWSQByteArrayToImageFile) GetProcAddress(hWSQ_library, "_SaveWSQByteArrayToImageFile");
   pSetShowFilePropertiesDialog = (SetShowFilePropertiesDialog) GetProcAddress(hWSQ_library, "_SetShowFilePropertiesDialog");
   pShowFileConverter = (ShowFileConverter) GetProcAddress(hWSQ_library, "_ShowFileConverter");
   pWSQ_decode_stream = (WSQ_decode_stream) GetProcAddress(hWSQ_library, "_WSQ_decode_stream");
   pWSQ_encode_stream = (WSQ_encode_stream) GetProcAddress(hWSQ_library, "_WSQ_encode_stream");
   pConvertHBITMAPtoGrayScale256 = (ConvertHBITMAPtoGrayScale256) GetProcAddress(hWSQ_library, "_ConvertHBITMAPtoGrayScale256");
   pSaveHBITMAPtoFileAsGrayScale256BMP = (SaveHBITMAPtoFileAsGrayScale256BMP) GetProcAddress(hWSQ_library, "_SaveHBITMAPtoFileAsGrayScale256BMP");

																							



   if (pRegisterWSQ == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of RegisterWSQ failed", L"Error", MB_OK );}
   if (pCreateBMPFromFile == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of SaveBMPToFile failed", L"Error", MB_OK );}
   if (pSaveBMPToFile == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of CreateBMPFromFile failed", L"Error", MB_OK );}
							  
																								  
   if (pCreateBMPFromWSQByteArray == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of CreateBMPFromWSQByteArray failed", L"Error", MB_OK );}
   if (pSaveWSQByteArrayToImageFile == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of SaveWSQByteArrayToImageFile failed", L"Error", MB_OK );}
   if (pSetShowFilePropertiesDialog == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of SetShowFilePropertiesDialog failed", L"Error", MB_OK );}
   if (pShowFileConverter == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of ShowFileConverter failed", L"Error", MB_OK );}
   if (pWSQ_decode_stream == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of WSQ_decode_stream failed", L"Error", MB_OK );}
   if (pWSQ_encode_stream == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of WSQ_encode_stream failed", L"Error", MB_OK );}
   if (pConvertHBITMAPtoGrayScale256 == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of ConvertHBITMAPtoGrayScale256 failed", L"Error", MB_OK );}
   if (pSaveHBITMAPtoFileAsGrayScale256BMP == NULL)
   {Application->MessageBox( L"Error: GetProcAddress of SaveHBITMAPtoFileAsGrayScale256BMP failed", L"Error", MB_OK );}







}

//---------------------------------------------------------------------------
__fastcall TMainForm::~TMainForm()

{
											 
											 
											  


					   


}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OpenButtonClick(TObject *Sender)
{


//    HBITMAP hBitmap = NULL;

//    TOpenDialog *open_dialog = new TOpenDialog(this);
    TOpenDialog *open_dialog = new TOpenDialog(NULL);

    open_dialog->Filter = L"All images|*.wsq;*.bmp;*.tiff;*.tif;*.jpg;*.jp2;*.jpc;*.jpe;*.jpeg;*.png;*.gif;*.iff;*.ico;*.wmf;"
L"*.emf;*.jfif;*.rle;*.dib;*.win;*.vst;*.vda;*.tga;*.icb;*.fax;*.eps;*.pcx;*.pcc;*.scr; *.rpf;*.rla;*.sgi;"
L"*.rgba;*.rgb;*.bw;*.psd;*.pdd;*.ppm;*.pgm;*.pbm;*.cel;*.pic;*.pcd;*.cut;*.psp|"
L"FBI Wavelet Scalar Quantization (*.wsq)|*.wsq|"
L"Windows bitmaps (*.bmp)|*.bmp|"
L"Macintosh TIFF images (*.tiff)|*.tiff|"
L"PC TIFF images (*.tif)|*.tif|"
L"JPG images (*.jpg)|*.jpg|"
L"JPEG-2000 Part-1 (*.jp2)|*.jp2|"
L"JPEG-2000 Code Stream (*.jpc)|*.jpc|"
L"JPE images (*.jpe)|*.jpe|"
L"JPEG images (*.jpeg)|*.jpeg|"
L"Portable network graphic images (*.png)|*.png|"
L"Compuserve Graphic Interchange Format(*.gif)|*gif|"
L"Paintshop Pro images (*.psp)|*.psp|"
L"JFIF images (*.jfif)|*.jfif|"
L"Run length encoded Windows bitmaps (*.rle)|*.rle|"
L"Device independant Windows bitmaps (*.dib)|*.dib|"
L"Truevision images (*.win)|*.win|"
L"Truevision images (*.vst)|*.vst|"
L"Truevision images (*.vda)|*.vda|"
L"Truevision images (*.tga)|*.tga|"
L"Truevision images (*.icb)|*.icb|"
L"GFI fax images (*.fax)|*.fax|"
L"Encapsulated Postscript images (*.eps)|*.eps|"
L"ZSoft Paintbrush images (*.pcx)|*.pcx|"
L"ZSoft Paintbrush images (*.pcc)|*.pcc|"
L"Word 5.x screen capture images (*.scr)|*.scr|"
L"Alias/Wavefront images (*.rpf)|*.rpf|"
L"Alias/Wavefront images (*.rla)|*.rla|"
L"SGI true color images (*.sgi)|*.sgi|"
L"SGI true color images with alpha (*.rgba)|*.rgba|"
L"SGI true color images (*.rgb)|*.rgb|"
L"SGI black/white images (*.bw)|*.bw|"
L"Photoshop images (*.psd)|*.psd|"
L"Photoshop images (*.pdd)|*.pdd|"
L"Portable pixel map images (*.ppm)|*.ppm|"
L"Portable gray map images (*.pgm)|*.pgm|"
L"Portable bitmap images (*.pbm)|*.pbm|"
L"Autodesk images (*.cel)|*.cel|"
L"Autodesk images (*.pic)|*.pic|"
L"Kodak Photo-CD images (*.pcd)|*.pcd|"
L"Dr. Halo images (*.cut)|*.cut|"
L"Amiga Bitmap Graphic (8 bits)|*.iff|"
L"Windows icons (*.ico)|*.ico|"
L"Windows metafiles (*.wmf)|*.wmf|"
L"Windows enhanced meta files (*.emf)|*.emf";



    if ( open_dialog->Execute() )
    {

	   hBitmap = (pCreateBMPFromFile)(System::UTF8Encode(open_dialog->FileName).c_str());



        if ( hBitmap )
        {
            SaveButton->Enabled = true;
// Take and use Handle of HBitmap directly from WSQ image library DLL.
// If the WSQ image library is called to load or save another picture, you will lose the current image
          OutputImage->Picture->Bitmap->Handle = hBitmap;

//Make a copy of hBitmap into OutputImage->Picture
//            OutputImage->Picture->Bitmap->Handle  = (HBITMAP)CopyImage((HANDLE)hBitmap, IMAGE_BITMAP, 0, 0,LR_COPYRETURNORG);

            OutputImage->Width = OutputImage->Picture->Bitmap->Width;
            OutputImage->Height = OutputImage->Picture->Bitmap->Height;
            Invalidate();
        }
        else
        {
            Application->MessageBox(L"Unable to load file", L"WSQ library error", MB_OK | MB_ICONERROR );
        }
    }

    delete open_dialog;





}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveButtonClick(TObject *Sender)
{




	TSaveDialog *save_dialog = new TSaveDialog( this );
	save_dialog->Filter = L"WSQ Files (*.wsq)|*.wsq|"
L"Windows BMP (*.bmp)|*.bmp|"
L"TIFF Files (*.tif)|*.tif|"
L"PNG Files (*.png)|*.png|"
L"JPEG Files (*.jpg)|*.jpg|"
L"Targa Files (*.tga)|*.tga|"
L"SGI Files (*.rgb)|*.rgb|"
L"JPEG-2000 Part-1 (*.jp2)|*.jp2|"
L"JPEG-2000 Code Stream (*.jpc)|*.jpc|"
L"PBM - Portable Bitmap Format (*.pbm)|*.pbm|"
L"PGM - Portable Graymap Format (*.pgm)|*.pgm|"
L"PPM - Portable Pixmap Format (*.ppm)|*.ppm";

	save_dialog->DefaultExt = "wsq";



	if ( save_dialog->Execute() )
	{
	  (pSetShowFilePropertiesDialog)(1);
	  (pSaveBMPToFile)(OutputImage->Picture->Bitmap->Handle, System::UTF8Encode(save_dialog->FileName).c_str(), save_dialog->FilterIndex);
	}

	delete save_dialog;


}
//---------------------------------------------------------------------------

void __fastcall TMainForm::RegisterButtonClick(TObject *Sender)
{

(pRegisterWSQ)();

}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FormShow(TObject *Sender)
{


Left = (Screen->Width - Width)/2;
Top = (Screen->Height - Height)/2;


}
//---------------------------------------------------------------------------

void __fastcall TMainForm::WSQtoStreamButtonClick(TObject *Sender)
{



    TOpenDialog *open_dialog = new TOpenDialog(NULL);

    open_dialog->Filter = "FBI Wavelet Scalar Quantization (*.wsq)|*.wsq";
    if ( open_dialog->Execute() ) {


   handle = _wopen(open_dialog->FileName.c_str(), O_RDONLY);

   if((ret = filelength(handle)) < 0)
   {Application->MessageBox( L"Error: filelength < 0", L"Error", MB_OK );}
   input_stream_length = ret;


   if((infp = _wfopen(open_dialog->FileName.c_str(), L"rb")) == (FILE *)NULL)
   {Application->MessageBox( L"Error: open file failed", L"Error", MB_OK );}

   input_data_stream = (unsigned char *)malloc(input_stream_length * sizeof(unsigned char));
   if(input_data_stream == (unsigned char *)NULL)
   {Application->MessageBox( L"Error: malloc for input_data_stream failed", L"Error", MB_OK );}

   n = fread(input_data_stream, sizeof(unsigned char), input_stream_length, infp);
   if(n != input_stream_length)
   {Application->MessageBox( L"Error: reading file failed", L"Error", MB_OK );}

   fclose(infp);

   close(handle);

// THE DECODING OF WSQ STREAM INTO DECOMPRESSED STREAM
(pWSQ_decode_stream)(input_data_stream, input_stream_length, &output_data_stream, &width, &height, &ppi, &comment_text);


    //Converts WSQ compressed byte array into HBITMAP for showing on screen
    hBitmap = (pCreateBMPFromWSQByteArray)(input_data_stream, input_stream_length);
    // Saves WSQ compressed byte array to an image file.
    //(pSaveWSQByteArrayToImageFile)(input_data_stream, input_stream_length, "C:\\OutputDirectory\\output.jpg", 5);

   if(input_data_stream != (unsigned char*)NULL)
   {free(input_data_stream); input_data_stream = (unsigned char*)NULL;}


        if ( hBitmap )
        {
// Take and use Handle of HBitmap directly from WSQ image library DLL.
// If the WSQ image library is called to load or save another picture, you will lose the current image
          OutputImage->Picture->Bitmap->Handle = hBitmap;

//Make a copy of hBitmap into OutputImage->Picture
//            OutputImage->Picture->Bitmap->Handle  = (HBITMAP)CopyImage((HANDLE)hBitmap, IMAGE_BITMAP, 0, 0,LR_COPYRETURNORG);

            OutputImage->Width = OutputImage->Picture->Bitmap->Width;
            OutputImage->Height = OutputImage->Picture->Bitmap->Height;
            Invalidate();
        }
        else
        {
            Application->MessageBox(L"Error: unable to decompress WSQ byte array.", L"WSQ library error", MB_OK | MB_ICONERROR );
        }


Application->MessageBox(L"WSQ file was loaded into memory stream and decompressed into another memory stream.\nNow please press button \"stream -> WSQ\" to compress memory stream and save it to file.\nWSQ compressed byte array was converted to HBITMAP for showing on screen.", L"WSQ image library", MB_OK );





    }

    StreamToWSQButton->Enabled = true;


}
//---------------------------------------------------------------------------

void __fastcall TMainForm::StreamToWSQButtonClick(TObject *Sender)
{



    TSaveDialog *save_dialog = new TSaveDialog( this );
    save_dialog->Filter = "WSQ Files (*.wsq)|*.wsq";
    save_dialog->DefaultExt = "wsq";

    if ( save_dialog->Execute() )
    {


bitrate = 0.75;
ppi = 500;
//comment_text2 = NULL;
comment_text2 = "Cognaxon";


   if(input_data_stream2 != (unsigned char*)NULL)
   {free(input_data_stream2); input_data_stream2 = (unsigned char*)NULL;}

   input_data_stream2 = (unsigned char *)malloc((width*height) * sizeof(unsigned char));
   if(input_data_stream2 == (unsigned char *)NULL)
   {Application->MessageBox( L"Error: malloc for input_data_stream2 failed", L"Error", MB_OK );}



    int row, row2, pixel_number, pixel_number2;

	// MAKE A MIRRORED/FLIPPED IMAGE (UP<->DOWN and LEFT<->RIGHT)
    for (int y = 0; y < height; y++)
    {
        row = width * y;
		row2 = width * (height - y - 1);
        for (int x = 0;  x < width; x++)
        {
         pixel_number = row + x;
		 pixel_number2 = row2 + (width - x - 1);

         input_data_stream2[pixel_number2] = output_data_stream[pixel_number];
        }
    }


// THE ENCODING OF DECOMPRESSED STREAM INTO WSQ STREAM
(pWSQ_encode_stream)(input_data_stream2, width, height, bitrate, ppi, comment_text2, &output_data_stream2, &output_stream2_length);

if(comment_text != NULL)
{
free(comment_text);
comment_text = (char*) NULL; // this prevents crashing when opening next WSQ image
}


   if((outfp = _wfopen(save_dialog->FileName.c_str(), L"wb")) == NULL)
   {Application->MessageBox( L"Error: open file failed", L"Error", MB_OK );}


   if((n = fwrite(output_data_stream2, 1, output_stream2_length, outfp)) != output_stream2_length)
   {Application->MessageBox( L"Error: write to file failed", L"Error", MB_OK );}

   fclose(outfp);


Application->MessageBox(L"Memory stream was compressed into another memory stream and saved to WSQ file.\nNow please press button \"Open\", select the saved file, open it and have a look at the\nresults of memory stream processing. The processed image is mirrored/flipped\n(UP<->DOWN and LEFT<->RIGHT).", L"WSQ image library", MB_OK );

  }


}
//---------------------------------------------------------------------------
