//  Copyright (C) 2018-2022  SEIKO EPSON CORPORATION
//
//  License: LGPL-2.1+
//  Author : SEIKO EPSON CORPORATION
//
//  This file is part of the 'Epson Scan 2' package.
//	 This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.

//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//  
//  ControllerTest.cpp -- template and derived ESC/I ESC/I-2 protocol commands

#include "gtest/gtest.h"
#include "EpsonScan2.h"
#include <stdio.h>
#include <dlfcn.h>
#include <iostream>
#include <boost/format.hpp>
class ControllerTest : public ::testing::Test {
public:
void* es2lib_;
SDIDeviceFinder_CreatePtr SDIDeviceFinder_CreatePtr_;
SDIDeviceFinder_DisposePtr SDIDeviceFinder_DisposePtr_;
SDIDeviceFinder_StartDiscoveryPtr SDIDeviceFinder_StartDiscoveryPtr_;
SDIDeviceFinder_StopDiscoveryPtr SDIDeviceFinder_StopDiscoveryPtr_;
SDIDeviceFinder_GetDevicesPtr SDIDeviceFinder_GetDevicesPtr_;
SDIScannerDriver_CreatePtr SDIScannerDriver_CreatePtr_;
SDIScannerDriver_OpenPtr SDIScannerDriver_OpenPtr_;
SDIScannerDriver_ClosePtr SDIScannerDriver_ClosePtr_;
SDIScannerDriver_DisposePtr SDIScannerDriver_DisposePtr_;
SDIScannerDriver_SetValuePtr SDIScannerDriver_SetValuePtr_;
SDIScannerDriver_GetValuePtr SDIScannerDriver_GetValuePtr_;
SDIScannerDriver_GetCapabilityPtr SDIScannerDriver_GetCapability_;
SDIScannerDriver_DoScanJobPtr SDIScannerDriver_DoScanJobPtr_;
SDIScannerDriver_GetNextTransferEventPtr SDIScannerDriver_GetNextTransferEventPtr_;
SDIImage_CreatePtr SDIImage_CreatePtr_;
SDIImage_GetPathPtr SDIImage_GetPathPtr_;
SDIImage_DisposePtr SDIImage_DisposePtr_;
SDIImage_GetWidthPtr SDIImage_GetWidthPtr_;
SDIImage_GetHeightPtr SDIImage_GetHeightPtr_;
SDIImage_GetSamplesPerPixelPtr SDIImage_GetSamplesPerPixelPtr_;
SDIImage_GetBitsPerSamplePtr SDIImage_GetBitsPerSamplePtr_;
virtual void SetUp() {
  es2lib_ = dlopen("./libepsonscan2.so", RTLD_LAZY);
  printf("%s", dlerror());
  ASSERT_TRUE(es2lib_ != nullptr);
  SDIDeviceFinder_CreatePtr_ = (SDIDeviceFinder_CreatePtr)dlsym(es2lib_, "SDIDeviceFinder_Create");
  ASSERT_TRUE(SDIDeviceFinder_CreatePtr_ != nullptr);
  SDIDeviceFinder_StartDiscoveryPtr_ = (SDIDeviceFinder_StartDiscoveryPtr)dlsym(es2lib_, "SDIDeviceFinder_StartDiscovery");
  ASSERT_TRUE(SDIDeviceFinder_StartDiscoveryPtr_ != nullptr);
  SDIDeviceFinder_StopDiscoveryPtr_ = (SDIDeviceFinder_StopDiscoveryPtr)dlsym(es2lib_, "SDIDeviceFinder_StopDiscovery");
  ASSERT_TRUE(SDIDeviceFinder_StopDiscoveryPtr_ != nullptr);
  SDIDeviceFinder_GetDevicesPtr_ = (SDIDeviceFinder_GetDevicesPtr)dlsym(es2lib_, "SDIDeviceFinder_GetDevices");
  ASSERT_TRUE(SDIDeviceFinder_GetDevicesPtr_ != nullptr);
  SDIDeviceFinder_DisposePtr_ = (SDIDeviceFinder_DisposePtr)dlsym(es2lib_, "SDIDeviceFinder_Dispose");
  ASSERT_TRUE(SDIDeviceFinder_DisposePtr_ != nullptr);
  SDIScannerDriver_CreatePtr_ = (SDIScannerDriver_CreatePtr)dlsym(es2lib_, "SDIScannerDriver_Create");
  ASSERT_TRUE(SDIDeviceFinder_CreatePtr_ != nullptr);
  SDIScannerDriver_OpenPtr_ = (SDIScannerDriver_OpenPtr)dlsym(es2lib_, "SDIScannerDriver_Open");
  ASSERT_TRUE(SDIScannerDriver_OpenPtr_ != nullptr);
  SDIScannerDriver_ClosePtr_ = (SDIScannerDriver_ClosePtr)dlsym(es2lib_, "SDIScannerDriver_Close");
  ASSERT_TRUE(SDIScannerDriver_ClosePtr_ != nullptr);
  SDIScannerDriver_DisposePtr_ = (SDIScannerDriver_DisposePtr)dlsym(es2lib_, "SDIScannerDriver_Dispose");
  ASSERT_TRUE(SDIScannerDriver_DisposePtr_ != nullptr);
  SDIScannerDriver_GetValuePtr_ = (SDIScannerDriver_GetValuePtr)dlsym(es2lib_, "SDIScannerDriver_GetValue");
  ASSERT_TRUE( SDIScannerDriver_GetValuePtr_ != nullptr);
  SDIScannerDriver_SetValuePtr_ = (SDIScannerDriver_GetValuePtr)dlsym(es2lib_, "SDIScannerDriver_SetValue");
  ASSERT_TRUE( SDIScannerDriver_SetValuePtr_ != nullptr);
  SDIScannerDriver_GetCapability_ = (SDIScannerDriver_GetCapabilityPtr)dlsym(es2lib_, "SDIScannerDriver_GetCapability");
  ASSERT_TRUE( SDIScannerDriver_GetCapability_ != nullptr);
  SDIScannerDriver_DoScanJobPtr_ = (SDIScannerDriver_DoScanJobPtr)dlsym(es2lib_, "SDIScannerDrive_DoScanJob");
  ASSERT_TRUE( SDIScannerDriver_DoScanJobPtr_ != nullptr);
  SDIScannerDriver_GetNextTransferEventPtr_ = (SDIScannerDriver_GetNextTransferEventPtr)dlsym(es2lib_, "SDIScannerDriver_GetNextTransferEvent");
  ASSERT_TRUE( SDIScannerDriver_GetNextTransferEventPtr_ != nullptr);
  SDIImage_CreatePtr_ = (SDIImage_CreatePtr)dlsym(es2lib_, "SDIImage_Create");
  ASSERT_TRUE( SDIImage_CreatePtr_ != nullptr);
  SDIImage_GetPathPtr_ = (SDIImage_GetPathPtr)dlsym(es2lib_, "SDIImage_GetPath");
  ASSERT_TRUE( SDIImage_GetPathPtr_ != nullptr);
  SDIImage_DisposePtr_ = (SDIImage_DisposePtr)dlsym(es2lib_, "SDIImage_Dispose");
  ASSERT_TRUE( SDIImage_GetPathPtr_ != nullptr);
  SDIImage_GetWidthPtr_ = (SDIImage_GetWidthPtr)dlsym(es2lib_, "SDIImage_GetWidth");
  ASSERT_TRUE( SDIImage_GetWidthPtr_ != nullptr);
  SDIImage_GetHeightPtr_ = (SDIImage_GetWidthPtr)dlsym(es2lib_, "SDIImage_GetHeight");
  ASSERT_TRUE( SDIImage_GetHeightPtr_ != nullptr);
  SDIImage_GetSamplesPerPixelPtr_ = (SDIImage_GetSamplesPerPixelPtr)dlsym(es2lib_, "SDIImage_GetSamplesPerPixel");
  ASSERT_TRUE( SDIImage_GetSamplesPerPixelPtr_ != nullptr);
  SDIImage_GetBitsPerSamplePtr_ = (SDIImage_GetBitsPerSamplePtr)dlsym(es2lib_, "SDIImage_GetBitsPerSample");
  ASSERT_TRUE( SDIImage_GetBitsPerSamplePtr_ != nullptr);
}
virtual void TearDown() {
}
};
TEST_F(ControllerTest, FinderTest)
{
   SDIDeviceFinder* finder = nullptr;
    SDIDeviceFinder_CreatePtr_(&finder);
 SDIDeviceFinder_StartDiscoveryPtr_(finder, nullptr, nullptr);
 sleep(5);
 SDIDeviceFinder_StopDiscoveryPtr_(finder);
 SDIDeviceInfo* devices = nullptr;
 SDIInt count = 0;
 SDIDeviceFinder_GetDevicesPtr_(finder, &devices,&count);
 std::cout << " === dump devices start ==" << std::endl;
 for (int i = 0; i < count; i++) {
  SDIDeviceInfo devInfo = devices[i];
  std::cout << "displayname :" << devInfo.displayName << std::endl;
  std::cout << "ipAdder :" << devInfo.ipAddress << std::endl;
  std::cout << "productID :" << devInfo.productID << std::endl;
  std::cout << "ModelID:" << devInfo.modelID << std::endl;
 }
 std::cout << " === dump devices fin ==" << std::endl;
 SDIDeviceFinder_DisposePtr_(finder);
 finder = nullptr;
}
TEST_F(ControllerTest, DriverTest)
{
 std::cout << " === Start Driver Test === " << std::endl;
 SDIScannerDriver* driver = nullptr;
 SDIDeviceInfo devInfo = {0};
 static const SDIInt kMyResolution = 50;
 static const SDIInt kSaveFormat = kSDIImageFormatJPEG;
 {
  strcpy(devInfo.modelID, "ES0129");
  strcpy(devInfo.displayName, "EPSON DS-530");
  devInfo.productID = 0x157;
 }
 {
  SDIScannerDriver_CreatePtr_(&driver, &devInfo, nullptr, nullptr);
  ASSERT_TRUE(driver != nullptr);
  std::cout << " Create OK " << std::endl;
  SDIScannerDriver_OpenPtr_(driver);
  std::cout << " Open OK " << std::endl;
 }
 {
  SDIFunctionalUnit current = kSDIFunctionalUnitDocumentFeeder;
  SDIFunctionalUnit out = (SDIFunctionalUnit)-1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIFunctionalUnitKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIFunctionalUnitKey, kSDIValueTypeInt, &out, sizeof(out));
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIFunctionalUnitKey, &capability);
  ASSERT_TRUE(out == kSDIFunctionalUnitDocumentFeeder);
  std::cout << "Functional Unit Test OK" << std::endl;
 }
 {
  SDIColorType current = kSDIColorTypeRGB24;
  SDIColorType out = (SDIColorType)-1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIColorTypeKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIColorTypeKey, kSDIValueTypeInt, &out, sizeof(out));
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIColorTypeKey, &capability);
  ASSERT_TRUE(out == kSDIColorTypeRGB24);
  std::cout << "ColorType Test OK" << std::endl;
 }
 {
  SDIInt current = kMyResolution;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIResolutionKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIResolutionKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == kMyResolution);
  std::cout << "Resolution Test OK" << std::endl;
 }
 {
  SDIImageFormat current = (SDIImageFormat)kSaveFormat;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIImageFormatKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIImageFormatKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == kSaveFormat);
  std::cout << "ImageFomat Test OK" << std::endl;
 }
 {
  SDIInt current = 8.27 * kMyResolution ;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIScanAreaWidthKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIScanAreaWidthKey, kSDIValueTypeInt, &out, sizeof(out));
  std::cout << "ScanArea Width Test OK" << std::endl;
 }
 {
  SDIInt current = 11.69 * kMyResolution ;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIScanAreaHeightKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIScanAreaHeightKey, kSDIValueTypeInt, &out, sizeof(out));
  std::cout << "ScanArea Height Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIScanAreaOffsetXKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIScanAreaOffsetXKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  std::cout << "ScanArea Location X Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIScanAreaOffsetYKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIScanAreaOffsetYKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  std::cout << "ScanArea Location Y Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIScannerDriver_GetValuePtr_(driver, kSDIMaxScanAreaWidthKey, kSDIValueTypeInt, &current, sizeof(current));
  ASSERT_TRUE(current != 0);
  std::cout << "ScanArea Max width " << current << std::endl;
 }
 {
  SDIInt current = 0;
  SDIScannerDriver_GetValuePtr_(driver, kSDIMaxScanAreaHeightKey, kSDIValueTypeInt, &current, sizeof(current));
  ASSERT_TRUE(current != 0);
  std::cout << "ScanArea Max height " << current << std::endl;
 }
 {
  SDIInt current = 0;
  SDIScannerDriver_GetValuePtr_(driver, kSDIMaxScanAreaHeightInLongPaperKey, kSDIValueTypeInt, &current, sizeof(current));
  ASSERT_TRUE(current != 0);
  std::cout << "ScanArea Max height In Long Paper " << current << std::endl;
 }
 {
  SDIInt current = kSDIDropoutColorRed;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIDropoutColorKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIDropoutColorKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(current == kSDIDropoutColorRed);
  current = kSDIDropoutColorNone;
  SDIScannerDriver_SetValuePtr_(driver, kSDIDropoutColorKey, kSDIValueTypeInt, &current, sizeof(current));
  std::cout << "Drop out test is ok " << current << std::endl;
 }
 {
  SDIInt current = kSDIOrientation90;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIOrientationKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIOrientationKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == kSDIOrientation90);
  std::cout << "Orientaion Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIMultiTiffEnabledKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIMultiTiffEnabledKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  std::cout << "MultiTiff Test OK" << std::endl;
 }
 {
  SDIInt current = kSDITiffCompressionCCITFAX4;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDITiffCompressionKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDITiffCompressionKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == kSDITiffCompressionCCITFAX4);
  std::cout << "TIFFCompression Test OK" << std::endl;
 }
 {
  SDIInt current = 50;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIContrastKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIContrastKey, kSDIValueTypeInt, &out, sizeof(out));
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIContrastKey, &capability);
  ASSERT_TRUE(out == 50);
  std::cout << "Contrast Test OK" << std::endl;
 }
  {
  SDIInt current = 50;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIBrightnessKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIBrightnessKey, kSDIValueTypeInt, &out, sizeof(out));
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIBrightnessKey, &capability);
  ASSERT_TRUE(out == 50);
  std::cout << "Brightness Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIThresholdKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIThresholdKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIThresholdKey, &capability);
  std::cout << "Threshold Test OK" << std::endl;
 }
 {
  SDIInt current = 90;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIJpegQuality, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIJpegQuality, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 90);
  std::cout << "JpegQuality Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIDuplexTypeKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIDuplexTypeKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIDuplexTypeKey, &capability);
  std::cout << "DuplexType Test OK" << std::endl;
 }
 {
  SDIInt out = -1;
  SDIScannerDriver_GetValuePtr_(driver, kSDIPaperLoadedKey, kSDIValueTypeInt, &out, sizeof(out));
  std::cout << "PaperLoaded Test OK" << std::endl;
 }
 {
  SDIInt current = 1;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIPagesTobeScannedKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIPagesTobeScannedKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 1);
  std::cout << "Pages to be scanned Test OK" << std::endl;
 }
 {
  SDIInt current = kSDIDoubleFeedDetectionLow;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIDoubleFeedDetectionKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIDoubleFeedDetectionKey, kSDIValueTypeInt, &out, sizeof(out));
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIDoubleFeedDetectionKey, &capability);
  ASSERT_TRUE(out == kSDIDoubleFeedDetectionLow);
  std::cout << "Double Feed Detection Test OK" << std::endl;
 }
 {
  SDIInt current = 30;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIBlankPageSkipLevelKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIBlankPageSkipLevelKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 30);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIBlankPageSkipLevelKey, &capability);
  std::cout << "BlankPageSkip Test OK" << std::endl;
 }
 {
  SDIInt current = 0;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIBackgroundRemovalKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIBackgroundRemovalKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 0);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIBackgroundRemovalKey, &capability);
  std::cout << "Background Removal Test OK" << std::endl;
 }
 {
  SDIInt current = 1;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIPaperDeskewKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIPaperDeskewKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 1);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIPaperDeskewKey, &capability);
  std::cout << "PaperDeskew Test OK" << std::endl;
 }
 {
  SDIInt current = kSDIAutoSizeStandard;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDIAutoSizeKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDIAutoSizeKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == kSDIAutoSizeStandard);
  std::cout << "AutoSize Test OK" << std::endl;
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIAutoSizeKey, &capability);
 }
 {
  SDIInt current = 1;
  SDIInt out = -1;
  SDIScannerDriver_SetValuePtr_(driver, kSDITransferCompressionKey, kSDIValueTypeInt, &current, sizeof(current));
  SDIScannerDriver_GetValuePtr_(driver, kSDITransferCompressionKey, kSDIValueTypeInt, &out, sizeof(out));
  ASSERT_TRUE(out == 1);
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDITransferCompressionKey, &capability);
  std::cout << "TransferCompression Test OK" << std::endl;
 }
 {
  SDICapability capability = {0};
  SDIScannerDriver_GetCapability_(driver, kSDIDoubleFeedDetectionKey, &capability);
  std::cout << "Capability Test OK" << std::endl;
 }
 {
  std::cout << "StartScanning..." << std::endl;
  SDIScannerDriver_DoScanJobPtr_(driver, kSDIOperationTypeNew);
  SDIInt isBlocking;
  SDITransferEventType outType = kSDITrasnferEventTypeImage;
  SDIImage* outImageData;
  SDIError outError;
  unsigned int nSize = 100;
  unsigned char* tmp_buf = (unsigned char*)::malloc(nSize);
  if(tmp_buf){
   memset(tmp_buf, 0, nSize);
  }
  SDIChar* output_path = (SDIChar*)tmp_buf;
  uint32_t imageCount = 0;
  while(outType != kSDITransferEventTypeComplete)
  {
   SDIImage_CreatePtr_(&outImageData);
   SDIScannerDriver_GetNextTransferEventPtr_(driver,
             &outType,
             outImageData,
             &outError);
   if (outType == kSDITrasnferEventTypeImage)
   {
    SDIImage_GetPathPtr_(outImageData, output_path, 0);
    std::string ext = "jpg";
    if (kSaveFormat == kSDIImageFormatJPEG)
    {
     ext = "jpg";
    }
    if (kSaveFormat == kSDIImageFormatPDF)
    {
     ext = "pdf";
    }
    if (kSaveFormat == kSDIImageFormatPNM)
    {
     ext = "pnm";
    }
    if (kSaveFormat == kSDIImageFormatTIFF)
    {
     ext = "tiff";
    }
    if (kSaveFormat == kSDIImageFormatPNG)
    {
     ext = "png";
    }
    if (kSaveFormat == kSDIImageFormatRaw)
    {
     ext = "raw";
    }
    if (rename(output_path, (boost::format("/tmp/epson/work/img_%2%.%1%") % ext.c_str() % imageCount).str().c_str()) != 0)
    {
     std::cout << "Rename failed" << std::endl;
    }
    std::cout << "=== Image Number === " << imageCount << std::endl;
    std::cout << "ImageWidth = " << SDIImage_GetWidthPtr_(outImageData) << std::endl;
    std::cout << "ImageHeight = " << SDIImage_GetHeightPtr_(outImageData) << std::endl;
    std::cout << "SamplesPerPixel = " << SDIImage_GetSamplesPerPixelPtr_(outImageData) << std::endl;
    std::cout << "BitsPerSample = " << SDIImage_GetBitsPerSamplePtr_(outImageData) << std::endl;
    imageCount++;
   }
   SDIImage_DisposePtr_(outImageData);
  }
  free(tmp_buf);
  tmp_buf = nullptr;
 }
 SDIScannerDriver_ClosePtr_(driver);
 std::cout << "Close OK" << std::endl;
 SDIScannerDriver_DisposePtr_(driver);
 std::cout << "Dispose OK" << std::endl;
 driver = nullptr;
}
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
