| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- // Vampyre Imaging Library Demo
- // Benchmark (C++, dll library usage, Win32)
- // tested in MSVC 8.0, BC++ 5.6.4
- // written by Marek Mauder
- //
- // This is not actually benchmark like ObjectPascal version because
- // all measured functions are called from external library, but it
- // shows how to use Imaging dll from C/C++ at least.
- //
- // Important:
- // 1) During the test large amounts of memory can be allocated by
- // the program (e.g. conversion from 3000x3000x64 bit image to 128 bit
- // requires over 200 MB of memory).
- // 2) Program's executable must be located in Demos\Bin,
- // or anywhere in the subdirectories of Demos\Cpp dir to be able to find
- // used data files.
- //
- // Compiled Imaging library must be located somewhere on system's
- // search path for this sample to work (usually VampyreImaging.dll
- // in C:\Windows or libVampyreImaging.so in /lib).
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <vector>
- #include <cstdio>
- #include "..\..\..\Source\Wrappers\Cpp\ImagingImport.h"
- using namespace Imaging;
- using namespace std;
- // Define this to write results to log file or undef it to
- // display them on screen.
- #define LOG_TO_FILE
- // Define this to write images created in saving test on disk.
- // They are saved only to memory when testing.
- #define SAVE_IMAGES_TO_FILES
- LARGE_INTEGER PerfFrequency;
- double InvPerfFrequency;
- const string SDataDir = "Data\\";
- const string SImageName = "Tigers";
- const string SSaveImage = "_BenchOut";
- const int BufSize = 8 * 1024 * 1024;
- enum TManipulation {maResize3k, maResize1k, maFlip, maMirror, maSwapChannels,
- maConvARGB64, maConvARGBF, maConvARGB16, maConvRGB24, maConvARGB32,
- maCompressDXT, maDecompressDXT, maReduceColors, maClone, maMipMaps,
- maCopyRect, maMapImage, maFill, maSplit, maMakePal, maReplace, maRotate180,
- maRotate90, maStretchRect};
- struct TFileFormatInfo
- {
- char Name[64];
- char Ext[16];
- char Masks[128];
- Boolean CanSave;
- Boolean IsMulti;
- };
- #ifdef LOG_TO_FILE
- fstream Out;
- #else
- // If logging to files is not defined standard cout is used
- ostream &Out = cout;
- #endif
- TImageData Img, ImgClone;
- LONGLONG Time;
- string Dir;
- char SaveBuf[BufSize];
- TImageDataList Subs = 0;
- TColor32Rec FillColor, NewColor;
- int I, XCount, YCount;
- PPalette32 Pal = NULL;
- vector<TFileFormatInfo> Formats;
- string GetAppDir(void);
- string GetDataDir(void);
- string GetImageName(const string &Ext);
- LONGLONG GetTimeMicroseconds(void);
- void LoadImage(const string &Name);
- void SaveImage(const string &Ext);
- void ManipulateImage(const TManipulation Man);
- int main(int argc, char ** argv)
- {
- char tmp;
- int Major, Minor, Patch;
- Dir = argv[0];
- FillColor.Color = 0xFFFF0000;
- NewColor.Color = 0xFF00CCFF;
- QueryPerformanceFrequency(&PerfFrequency);
- InvPerfFrequency = (double)1.0 / PerfFrequency.QuadPart;
- #ifdef LOG_TO_FILE
- // if logging to file is defined new output file is created
- // and all messages are written into it
- Out.open("ResultsCpp.log", ios::out);
- cout << "Benchmarking..." << endl;
- #endif
- // This call must be made before any atempt to use any Imaging function.
- // Everything is imported from dll here.
- ImLoadLibrary();
- // Call this before any manipulation with TImageData record
- ImInitImage(&Img);
-
- ImGetVersion(&Major, &Minor, &Patch);
- Out << "Vampyre Imaging Library Benchmark Demo (C++) version " <<
- Major << '.' << Minor << '.' << Patch << endl << endl;
- I = 0;
- Formats.resize(1);
- // Enumerate all supported file formats and store their properties
- // to dyn array. After each iteration dyn array's size is increased by one
- // so next call to EnumFileFormats will have free space for results.
- // After enumerating last array item should be deleted because its empty.
- while (ImEnumFileFormats(&I, Formats[I].Name, Formats[I].Ext, Formats[I].Masks, &Formats[I].CanSave, &Formats[I].IsMulti))
- Formats.resize(I + 1);
- Formats.resize(I);
- // Test image loading functions for all supported image file formats
- // note that image loaded in one LoadImage is automaticaly
- // freed in then next LoadImage call so no leaks (should) occurr.
- Out << "------------- Loading Images -------------" << endl;
- for (I = 0; I < (int)Formats.size(); I++)
- LoadImage(GetImageName(Formats[I].Ext));
- // Test image manipulation functions like conversions, resizing and other
- Out << endl << "----------- Image Manipulation -----------" << endl;
- ManipulateImage(maResize3k);
- ManipulateImage(maConvARGB64);
- ManipulateImage(maFlip);
- ManipulateImage(maMirror);
- ManipulateImage(maSwapChannels);
- ManipulateImage(maConvARGBF);
- ManipulateImage(maConvARGB16);
- ManipulateImage(maConvARGB32);
- ManipulateImage(maClone);
- ManipulateImage(maCopyRect);
- ManipulateImage(maFill);
- ManipulateImage(maStretchRect);
- ManipulateImage(maReplace);
- ManipulateImage(maMipMaps);
- ManipulateImage(maSplit);
- ManipulateImage(maResize1k);
- ManipulateImage(maRotate180);
- ManipulateImage(maRotate90);
- ManipulateImage(maReduceColors);
- ManipulateImage(maMakePal);
- ManipulateImage(maMapImage);
- ManipulateImage(maCompressDXT);
- ManipulateImage(maDecompressDXT);
- ManipulateImage(maConvRGB24);
- // Test image saving functions. Image is now in R8G8B8 format. Note that
- // some supported file formats cannot save images in R8G8B8 so their
- // time includes conversions.
- Out << endl << "------------- Saving Images --------------" << endl;
- for (I = 0; I < (int)Formats.size(); I++)
- {
- if (Formats[I].CanSave)
- SaveImage(Formats[I].Ext);
- }
- // Image must be freed in the end
- ImFreeImage(&Img);
- // Call this if you no longer need to use Imaging functions
- // Imaging dll is unloaded here
- ImFreeLibrary();
- #ifdef LOG_TO_FILE
- Out.close();
- cout << "Results written to 'ResultsCpp.log' file." << endl;
- #endif
- cout << "Press any key to exit" << endl;
- cin.get(tmp);
- return 0;
- }
- string GetAppDir(void)
- {
- int Idx;
- string Res = Dir;
- Idx = static_cast<int>(Res.rfind("\\"));
- if (Idx > 0)
- Res.erase(Idx + 1);
- return Res;
- }
- string GetDataDir(void)
- {
- int Idx;
- string Res = Dir;
- Idx = static_cast<int>(Res.find("Bin\\"));
- if (Idx >= 0)
- return Res.erase(Idx) + SDataDir;
- Idx = static_cast<int>(Res.find("Cpp\\"));
- if (Idx >= 0)
- return Res.erase(Idx) + SDataDir;
- return Res;
- }
- string GetImageName(const string &Ext)
- {
- return GetDataDir() + SImageName + '.' + Ext;
- }
- LONGLONG GetTimeMicroseconds(void)
- {
- LARGE_INTEGER Time;
- QueryPerformanceCounter(&Time);
- return static_cast<LONGLONG>(1000000 * InvPerfFrequency * Time.QuadPart);
- }
- void LoadImage(const string &Name)
- {
- FILE *File = fopen(Name.c_str(), "rb");
- if (File == NULL)
- return;
- else
- fclose(File);
-
- Out << "Loading image: " << Name << endl;
- Time = GetTimeMicroseconds();
- ImLoadImageFromFile(Name.c_str(), &Img);
- Out << "Image loaded in: " << GetTimeMicroseconds() - Time << " us" << endl;
- }
- void SaveImage(const string &Ext)
- {
- int Size = BufSize;
- Out << "Saving image to format: " << Ext << endl;
- Time = GetTimeMicroseconds();
- ImSaveImageToMemory(Ext.c_str(), (void*)SaveBuf, &Size, &Img);
- Out << "Image saved in: " << GetTimeMicroseconds() - Time << " us" << endl;
- #ifdef SAVE_IMAGES_TO_FILES
- ImSaveImageToFile((GetAppDir() + SSaveImage + '.' + Ext).c_str(), &Img);
- #endif
- }
- void ManipulateImage(const TManipulation Man)
- {
- // According to the enum value image manipulation functions are
- // called and measured.
- switch (Man)
- {
- case maResize3k:
- Out << "Resizing image to 3000x3000 (bilinear) ..." << endl;
- Time = GetTimeMicroseconds();
- ImResizeImage(&Img, 3000, 3000, rfBilinear);
- Out << "Image resized in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maResize1k:
- Out << "Resizing image to 1000x1000 (bicubic) ..." << endl;
- Time = GetTimeMicroseconds();
- ImResizeImage(&Img, 1000, 1000, rfBicubic);
- Out << "Image resized in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maFlip:
- Out << "Flipping image ..." << endl;
- Time = GetTimeMicroseconds();
- ImFlipImage(&Img);
- Out << "Image flipped in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maMirror:
- Out << "Mirroring image ..." << endl;
- Time = GetTimeMicroseconds();
- ImMirrorImage(&Img);
- Out << "Image mirrored in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maSwapChannels:
- Out << "Swapping channels of image ..." << endl;
- Time = GetTimeMicroseconds();
- ImSwapChannels(&Img, ChannelRed, ChannelGreen);
- Out << "Channels swapped in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maConvARGB64:
- Out << "Converting image to A16R16G16B16 64bit format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifA16R16G16B16);
- Out << "Image converted in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maConvARGBF:
- Out << "Converting image to A32B32G32R32F 128bit floating point format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifA32B32G32R32F);
- Out << "Image converted in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maConvARGB16:
- Out << "Converting image to A4R4G4B4 16bit format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifA4R4G4B4);
- Out << "Image converted in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maConvRGB24:
- Out << "Converting image to R8G8B8 24bit format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifR8G8B8);
- Out << "Image converted in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maConvARGB32:
- Out << "Converting image to A8R8G8B8 32bit format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifA8R8G8B8);
- Out << "Image converted in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maCompressDXT:
- Out << "Compressing image to DXT1 format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifDXT1);
- Out << "Image compressed in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maDecompressDXT:
- Out << "Decompressing image from DXT1 format ..." << endl;
- Time = GetTimeMicroseconds();
- ImConvertImage(&Img, ifA8R8G8B8);
- Out << "Image decompressed in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maReduceColors:
- Out << "Reducing colors count to 1024 ..." << endl;
- Time = GetTimeMicroseconds();
- ImReduceColors(&Img, 1024);
- Out << "Colors reduced in in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maMipMaps:
- Out << "Creating mipmaps ..." << endl;
- Time = GetTimeMicroseconds();
- ImGenerateMipMaps(&Img, 0, &Subs);
- Out << "Mipmaps created in: " << GetTimeMicroseconds() - Time << " us" << endl;
- ImFreeImageList(&Subs);
- break;
- case maClone:
- Out << "Cloning image ..." << endl;
- ImInitImage(&ImgClone);
- Time = GetTimeMicroseconds();
- ImCloneImage(&Img, &ImgClone);
- Out << "Image cloned in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maCopyRect:
- Out << "Copying rectangle ..." << endl;
- Time = GetTimeMicroseconds();
- ImCopyRect(&ImgClone, 0, 1500, 1500, 1500, &Img, 0, 0);
- Out << "Rectangle copied in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maStretchRect:
- Out << "Stretching rectangle (bicubic) ... " << endl;
- Time = GetTimeMicroseconds();
- ImStretchRect(&ImgClone, 0, 1500, 1500, 1500, &Img, 500, 500, 2000, 2000, rfBicubic);
- Out << "Rectangle stretched in: " << GetTimeMicroseconds() - Time << " us" << endl;
- ImFreeImage(&ImgClone);
- break;
- case maMapImage:
- Out << "Mapping image to existing palette ..." << endl;
- Time = GetTimeMicroseconds();
- ImMapImageToPalette(&Img, Pal, 256);
- Out << "Image mapped in: " << GetTimeMicroseconds() - Time << " us" << endl;
- ImFreePalette(&Pal);
- break;
- case maFill:
- Out << "Filling rectangle ..." << endl;
- Time = GetTimeMicroseconds();
- ImFillRect(&Img, 1500, 0, 1500, 1500, &FillColor);
- Out << "Rectangle filled in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maReplace:
- Out << "Replacing colors in rectagle ..." << endl;
- Time = GetTimeMicroseconds();
- ImReplaceColor(&Img, 0, 0, Img.Width, Img.Height, &FillColor, &NewColor);
- Out << "Colors replaced in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maSplit:
- Out << "Splitting image ..." << endl;
- Time = GetTimeMicroseconds();
- Subs = 0;
- ImSplitImage(&Img, &Subs, 300, 300, &XCount, &YCount, True, &FillColor);
- Out << "Image split in: " << GetTimeMicroseconds() - Time << " us" << endl;
- ImFreeImageList(&Subs);
- break;
- case maMakePal:
- Out << "Making palette for images ..." << endl;
- ImNewPalette(256, &Pal);
- ImInitImageList(1, &Subs);
- ImSetImageListElement(Subs, 0, &Img);
- Time = GetTimeMicroseconds();
- ImMakePaletteForImages(Subs, Pal, 256, False);
- Out << "Palette made in: " << GetTimeMicroseconds() - Time << " us" << endl;
- ImFreeImage(&Img);
- ImGetImageListElement(Subs, 0, &Img);
- ImFreeImageList(&Subs);
- break;
- case maRotate180:
- Out << "Rotating image 180 degrees CCW ... " << endl;
- Time = GetTimeMicroseconds();
- ImRotateImage(&Img, 180);
- Out << "Image rotated in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- case maRotate90:
- Out << "Rotating image 90 degrees CCW ... " << endl;
- Time = GetTimeMicroseconds();
- ImRotateImage(&Img, 90);
- Out << "Image rotated in: " << GetTimeMicroseconds() - Time << " us" << endl;
- break;
- }
- }
- /*
- Changes/Bug Fixes:
- -- 0.21 -----------------------------------------------------
- - Updated according to Object Pascal version of demo.
- -- 0.17 -----------------------------------------------------
- - made changes to be up to date with Pascal version
- (new tests, filtered resizing, ...)
- -- 0.15 -----------------------------------------------------
- - changed working with ImageDataList types because of change
- in header
- */
|