// Copyright (C) 2003-2026, Foxit Software Inc..
// All Rights Reserved.
//
// http://www.foxitsoftware.com
//
// The following code is copyrighted and contains proprietary information and trade secrets of Foxit Software Inc..
// You cannot distribute any part of Foxit PDF SDK to any third party or general public,
// unless there is a separate license agreement with Foxit Software Inc. which explicitly grants you such rights.
//
// This file contains an example to demonstrate how to use Foxit PDF SDK to convert images to PDF files.

#include "FSPDFObjC.h"

NSString *input_path = @"../input_files/";
NSString *output_path = @"../output_files/";

NSString* sn = @"bPxThFlBAYifO3yiW0C51bKbjPap1zHaf5aG5sX378TjFvB7Q0802A==";
NSString* key = @"8f3g1sGNtR8NAgfSNv+BvaJWy2fnrw36NZvzh8GUxYXvs+/YczAk4e34yqlOnmL4asgxGMO7+rlOcSHUSSKagx5g4G7VEXfkYLXnDDx77FOOedZPrFFcOCu1vT4+wOKzy1zkORq9cKtiFf44byH5sfRqf+OvELjep2teT9eF9yPCsSw2vRKljXlPy40DMP9XX1O5OTe+mSG3RvwKUMb0+RpG3YobM87j+/ynTDlJMMXw4vgwuTb1ZuAtlvkTdFz7HDLV81C6TYnn73ddHeGD3qYWBVsD4uJkDwyyH/SWr7QX0HSgVg8HSZqnab1VGdAUYxKY2vGWeOTJdu6qDGb5ZEb9O3kZZg+9LYAmUKzDfCYwfIsYZ8Y9LPC4wMx70kIq7JpNnzPvigrdshV8/ew1F0+qP/P5Z1EB53vDVrp2LVSuL873Wv4g3PzjZlNH+1qgT87hC+Buto4qsSUfP5Y2z0uApu+c/TfttCXbeMLSsw9TY1HQD3mkrZExMaQqRrAuXAcZWdvBnVuG3DCZmm8q0DLxJiCfYfViAU/AkbeKMIGaTJdrvIXBcssfde4nmU6qr0M4x4+Hs2ESddtY2QRtLAUBq/7h7GJlJHkEZr8ueaUy/6D/2vvAWz6wMLgmjlPbDTLqzfnCJylHCPtcJmu1SPPT9v1VreBX3+zNWcIT8HueyHEiUniqzwWkRKaotrnNb/zhnHLPpgaBSwKjyi8rOzzVwu/nY84G9ye4jsVjmkIRItKDrW7z22iS+QQuTwfqLVuMB0OD4jMkPCC2slzPfEeZnuh4+Rewln2qLRJVgI72zJ20OBWAelGSpO1Ii2Y3gOvojdmtUwx6R3Z1qFNWTTB25o9ytcux8BLOtTCkA8T8xaT4N339OTCsu/TmfahIDixKvr8cDa6F2WkBT8SOfv64W9PgiNv5B/BMOD2VWYaAl0N7yD0NkYYg/cDWRC4dfpdeip1jrr0k3mND0oSpIkxC+FicZbaYYwRdtJ9OSVWJ5OE0voLv8HgLze8mw6s4TrN3z+a2NQCveMa2VRN7YcEF7agPrvb/qU+otMwHae/wM7+f+HFAaOW+WTfzfxIVFB8/A1DN0NiEX+em4G7nO5F5ZcvfYPpaaioe8Nn33BbVLtMjXqsOBeM8AXiVfpD6YO75j7BqnBUPnivvD8BxJaaIQZvVSuQmvGm0ynt03IYwE8Rq+jYsunvsZ86jh5BiUR+Nm7sK0Qe9BdZn/7jdqohMv9czfMGUAscX+xBMunFbDpcRbWVpUADcm209L8Ndek2XY7YlCMxPgPVNvfWRF2jxehib9Tpd7zB5ZIDfAEH9zrpLfp29DLvCh2Yx8mH7xxdKG1O9Q0GdHphYHhej6smAcPm68R0GUQaTOLfXqNpueGJC1GAOI3Y4swjyt7jMTWcibnKLzwukWE5rnEDhn5n64JnyUM0ZFkRmtOiV";



typedef long long int       int64;
typedef unsigned long long  FILESIZE;



@interface FSFileReader : NSObject<FSFileReaderCallback>
@property (nonatomic) FILE* file_;
@property (nonatomic, strong) NSString* filePath;
-(BOOL)LoadFile:(NSString *)filePath;
//- (id)initWithSourceFilePath:(NSString *)path;
@end

@implementation FSFileReader

-(BOOL)LoadFile:(NSString *)filePath{
        self.filePath = filePath;
        const char* mfilePath = [filePath cStringUsingEncoding:NSUTF8StringEncoding];
        self.file_ = fopen(mfilePath, "rb");
        if (!self.file_)
            return NO;
        return TRUE;
    }
-(unsigned long long)getSize{
    if (!self.file_) return NO;
    fseek(self.file_, 0, SEEK_END);
    return (uint32)ftell(self.file_);
 }

-(NSData*)readBlock:(unsigned long long)offset  size:(unsigned long long)size {

	NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:self.filePath];
	[fileHandle seekToFileOffset:offset];
	NSData *data = [fileHandle readDataOfLength:size];
	return data;
}
@end

@interface FSFileWriterCallbackImpl : NSObject<FSFileWriterCallback>
@property (nonatomic) FILE* mfile;
@property (nonatomic, strong) NSString* filePath;
-(BOOL)LoadFile:(NSString *)filePath;
@end

@implementation FSFileWriterCallbackImpl
-(BOOL)LoadFile:(NSString *)filePath
{
    self.filePath = filePath;
    const char* mfilePath = [filePath cStringUsingEncoding:NSUTF8StringEncoding];
    self.mfile = fopen(mfilePath, "wb");
    if (!self.mfile) return NO;
    return TRUE;
}

-(unsigned long long)getSize {
    if (!self.mfile) return NO;
    
    fseek(self.mfile, 0, SEEK_END);
    return (uint32)ftell(self.mfile);
}

-(BOOL)writeBlock:(NSData*)data offset:(unsigned long long)offset {
    if (!self.mfile) return NO;
    
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:self.filePath];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:data];
    [fileHandle closeFile];
    
    return YES;
}

-(BOOL)flush {
    return YES;
}
@end


void Image2PDF(NSString *input_file, NSString *output_file) {
	FSImage *image = [[FSImage alloc] initWithPath:input_file];
	int count = 1;
	if ([image getType] != FSImageJBIG2) {
	    count = [image getFrameCount];
	}
	
	FSPDFDoc *doc = [[FSPDFDoc alloc] init];
	for (int i = 0; i < count; i ++) {
		float w = [image getWidth];
        float h = [image getHeight];
		FSPDFPage *page = [doc insertPage:i width:w height:h];
		FSPointF *ptZero = [[FSPointF alloc] init];
		ptZero.x = 0;
		ptZero.y = 0;       
		[page addImage:image frame_index:i position:ptZero width:w height:h auto_generate_content:YES];
	}
	
	[doc saveAs:output_file save_flags:FSPDFDocSaveFlagNoOriginal];
}

int main(int argc, const char * argv[]) {
	
	@autoreleasepool {
		NSString *output_directory = [output_path stringByAppendingString:@"image2pdf/"];
		
		NSFileManager *fileManager = [NSFileManager defaultManager];
		BOOL isDir = NO;
		if ([fileManager fileExistsAtPath:output_directory isDirectory:&isDir]) {
			if (!isDir) {
				NSError *error = nil;
				if (![fileManager removeItemAtPath:output_directory error:&error] || error) {
					return -1;
				}
				if (![fileManager createDirectoryAtPath:output_directory withIntermediateDirectories:YES attributes:nil error:&error] || error) {
					return -1;
				}
			}
		} else {
			NSError *error = nil;
			if (![fileManager createDirectoryAtPath:output_directory withIntermediateDirectories:YES attributes:nil error:&error] || error) {
				return -1;
			}
		}
		
		// Initialize library
		FSErrorCode errorCode = [FSLibrary initialize:sn key:key];
		if (errorCode != FSErrSuccess) {
			NSLog(@"Library Initialize Error: %ld", errorCode);
			return -1;
		}
		
		@try {
			{
				// Convert .bmp file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"watermark.bmp"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"watermark_bmp.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert BMP file to PDF file.");
			}
			{
				// Convert .jpg file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"image_samples.jpg"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"image_samples_jpg.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert JPG file to PDF file.");
			}
			{
				// Convert .tif file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"TIF2Pages.tif"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"TIF2Pages_tif.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert TIF file to PDF file.");
			}
			{
				// Convert .gif file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"image005.gif"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"image005_gif.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert GIF file to PDF file.");
			}
			
			{
				// Convert .png file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"1.png"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_png.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert PNG file to PDF file.");
			}
			{
				// Convert .jb2 file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"STR_039.jb2"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"STR_039_jb2.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert JB2 file to PDF file.");
			}
			{
				// Convert .jp2 file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jp2"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jp2.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert JP2 file to PDF file.");
			}
			{
				// Convert .jpx file to PDF document.
				NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jpx"];
				NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jpx.pdf"];
				Image2PDF(input_file,output_file);
				NSLog(@"Convert JPX file to PDF file.");
			}
		}
		@catch (NSException *e) {
			NSLog(@"Unknown Exception, %@", e);
			return -1;
		}
  @try {
    	{
      	NSLog(@"Start: convert file from file path.");
    		// Convert .bmp file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"watermark.bmp"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"watermark_bmp_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert BMP file to PDF file.");
    	}
    	{
    		// Convert .jpg file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"image_samples.jpg"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"image_samples_jpg_frompath.pdf"];
    		Image2PDF(input_file,output_file);
    		NSLog(@"Convert JPG file to PDF file.");
    	}
    	{
    		// Convert .tif file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"TIF2Pages.tif"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"TIF2Pages_tif_frompath.pdf"];
        [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert TIF file to PDF file.");
    	}
    	{
    		// Convert .gif file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"image005.gif"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"image005_gif_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert GIF file to PDF file.");
    	}
    	
    	{
    		// Convert .png file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.png"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_png_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert PNG file to PDF file.");
    	}

		{
			// Convert .jb2 file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"STR_039.jb2"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"STR_039_jb2_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
			NSLog(@"Convert JB2 file to PDF file.");
		}
    	{
    		// Convert .jp2 file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jp2"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jp2_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert JP2 file to PDF file.");
    	}
    	{
    		// Convert .jpx file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jpx"];
    		NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jpx_frompath.pdf"];
    		[FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert JPX file to PDF file.");
    	}
      NSLog(@"End: convert file from file path."); 
    }
    	@catch (NSException *e) {
    	NSLog(@"Unknown Exception, %@", e);
    	return -1;
    }
    
  @try {
    	{
      	NSLog(@"Start: convert file from stream.");
    		// Convert .bmp file to PDF document.
    	    NSString *input_file = [input_path stringByAppendingPathComponent:@"watermark.bmp"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"watermark_bmp_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
    	    NSLog(@"Convert BMP file to PDF file.");
    	}
    	{
    		// Convert .jpg file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"image_samples.jpg"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"image_samples_jpg_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
    		NSLog(@"Convert JPG file to PDF file.");
    	}
    	{
    		// Convert .tif file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"TIF2Pages.tif"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"TIF2Pages_tif_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert TIF file to PDF file.");
    	}
    	{
    		// Convert .gif file to PDF document.

    		NSString *input_file = [input_path stringByAppendingPathComponent:@"image005.gif"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"image005_gif_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert GIF file to PDF file.");
    	}
    	
    	{
    		// Convert .png file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.png"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_png_from_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert PNG file to PDF file.");
    	}
		{
			// Convert .jb2 file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"STR_039.jb2"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"STR_039_jb2_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
			NSLog(@"Convert JB2 file to PDF file.");
		}

    	{
    		// Convert .jp2 file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jp2"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jp2_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert JP2 file to PDF file.");
    	}
    	{
    		// Convert .jpx file to PDF document.
    		NSString *input_file = [input_path stringByAppendingPathComponent:@"1.jpx"];
			NSString *output_file = [output_directory stringByAppendingPathComponent:@"1_jpx_stream.pdf"];
		    FSFileReader *file_reader = [[FSFileReader alloc] init];
		    [file_reader LoadFile:input_file];
		    FSFileWriterCallbackImpl *filewriter = [[FSFileWriterCallbackImpl alloc] init];
		    [filewriter LoadFile:output_file];
		    [FSConvert fromImageWithStreamCallback:file_reader saved_pdf_filestream:filewriter];
            [FSConvert fromImage:input_file saved_pdf_path:output_file];
    		NSLog(@"Convert JPX file to PDF file.");
    	}
      NSLog(@"End: convert file from stream."); 
    }
    	@catch (NSException *e) {
    	NSLog(@"Unknown Exception, %@", e);
    	return -1;
    }
   }
   [FSLibrary destroy];
   return 0;
}
