// 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 verify if a PDF file is PDFA-1a version
// or convert a PDF file to PDFA-1a version.

#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";


void OutputPDFAFixupData(FSResultInformation* result_info, NSString* output_txt_path) {
	NSMutableString* info = [NSMutableString new];
	int fixup_count = [result_info getFixupDataCount];
	[info appendString:[NSString stringWithFormat:@"== Fixup Data, count:%d ==\r\n", fixup_count]];
	for (int i = 0; i<fixup_count; i++) {
        FSFixupData* fixup_data = [result_info getFixupData:i];
		[info appendString:[NSString stringWithFormat:@"Used count:%d\r\n", fixup_data.used_count]];

		[info appendString:@"Name:"];
		[info appendString:fixup_data.name];
		[info appendString:@"\r\n"];

		[info appendString:@"Comment:"];
		[info appendString:fixup_data.comment];
		[info appendString:@"\r\n"];

		[info appendString:@"Reason:"];
		int reason_count = [fixup_data.reasons count];
		if (reason_count < 1) {
			[info appendString:@"\r\n"];
		} else {
			for (int z = 0; z<reason_count; z++) {
				[info appendString:@"\t"];
                [info appendString:[fixup_data.reasons objectAtIndex:z]];
				[info appendString:@"\r\n"];
			}
		}

		[info appendString:[NSString stringWithFormat:@"State value:%ld\r\n", fixup_data.state]];
		[info appendString:@"\r\n"];
	}
	[[info dataUsingEncoding:NSUTF8StringEncoding] writeToFile:output_txt_path atomically:YES];
}

void OutputPDFAHitData(FSResultInformation* result_info, NSString* output_txt_path) {
	NSMutableString* info = [NSMutableString new];

	int hit_data_count = [result_info getHitDataCount];
	[info appendString:[NSString stringWithFormat:@"== Hit Data, count:%d ==\r\n", hit_data_count]];
	for (int i = 0; i<hit_data_count; i++) {
        FSHitData* hit_data = [result_info getHitData:i];
		[info appendString:[NSString stringWithFormat:@"Triggered count:%d\r\n", hit_data.triggered_count]];

		[info appendString:@"Name:"];
		[info appendString:hit_data.name];
		[info appendString:@"\r\n"];

		[info appendString:@"Comment:"];
		[info appendString:hit_data.comment];
		[info appendString:@"\r\n"];

		[info appendString:@"Trigger value:"];
		int trigger_value_count = [hit_data.trigger_values count];
		if (trigger_value_count < 1) {
			[info appendString:@"\r\n"];
		} else {
			for (int z = 0; z<trigger_value_count; z++) {
				[info appendString:@"\t"];
                [info appendString:[hit_data.trigger_values objectAtIndex:z]];
				[info appendString:@"\r\n"];
			}
		}

		[info appendString:[NSString stringWithFormat:@"Check severity:%ld\r\n", hit_data.severity]];
		[info appendString:[NSString stringWithFormat:@"Page index:%d\r\n", hit_data.page_index]];

		[info appendString:@"\r\n"];
	}
	[[info dataUsingEncoding:NSUTF8StringEncoding] writeToFile:output_txt_path atomically:YES];
}

@interface MyComplianceProgressCallback : NSObject<FSComplianceProgressCallback>
{
		@private
		NSMutableString* output_data_;
}
-(id)init;
-(void)saveProgressDataToFile:(NSString*)output_file_path;
@end

@implementation MyComplianceProgressCallback

-(id)init {
	output_data_ = [NSMutableString new];
	return self;
}

-(void)updateCurrentStateData: (int)current_rate current_state_string: (NSString*)current_state_string {
	NSLog(@"Current rate: %d", current_rate);
	
	[output_data_ appendString:[NSString stringWithFormat:@"Current rate:%d, state str:", current_rate]];
	[output_data_ appendString:current_state_string];
	[output_data_ appendString:@"\r\n"];
}

-(void)saveProgressDataToFile:(NSString*)output_file_path {
	[[output_data_ dataUsingEncoding:NSUTF8StringEncoding] writeToFile:output_file_path atomically:YES];
}
@end



int main(int argc, const char * argv[]) {
	
	@autoreleasepool {
		NSString *output_directory = [output_path stringByAppendingString:@"compliance/"];
		
		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;
		}
		
		NSString *input_file = [input_path stringByAppendingPathComponent:@"AboutFoxit.pdf"];
		
		@try {
			// "compliance_resource_folder_path" is the path of compliance resource folder. Please refer to Developer Guide for more details.
			NSString* compliance_resource_folder_path = @"";
			// If you use an authorization key for Foxit PDF SDK, please set a valid unlock code string to compliance_engine_unlockcode for FSComplianceEngine.
			// If you use an trial key for Foxit PDF SDK, just keep compliance_engine_unlockcode as an empty string.
			NSString* compliance_engine_unlockcode = @"";
			
			if ([compliance_resource_folder_path length] < 1) {
				NSLog(@"compliance_resource_folder_path is still empty. Please set it with a valid path to compliance resource folder path.");
				return -1;
			}
			// Initialize compliance engine.
			errorCode = [FSComplianceEngine initialize:compliance_resource_folder_path compliance_engine_unlockcode:compliance_engine_unlockcode];
			if (errorCode != FSErrSuccess) {
				switch (errorCode) {
					case FSErrInvalidLicense:
						NSLog(@"[Failed] Compliance module is not contained in current Foxit PDF SDK keys.\n");
						break;
					default:
						NSLog(@"[Failed] Fail to initialize compliance engine. Error: %ld", errorCode);
						break;
				}
				return -1;
			}
			NSLog(@"FSComplianceEngine is initialized.");

			// Set custom temp folder path for FSComplianceEngine. 
			//[FSComplianceEngine setTempFolderPath:@""];
			// Set languages. If not set language to FSComplianceEngine, "English" will be used as default.
			//[FSComplianceEngine setLanguage:@"Chinese-Simplified"];

			FSPDFACompliance* pdfa_compliance = [[FSPDFACompliance alloc] init];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFACompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfacompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfa_compliance verify:FSPDFAComplianceVersionPDFA1a src_pdf_path:input_file first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfacompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			NSString* save_pdf_path = [output_directory stringByAppendingPathComponent:@"1_pdfacompliance_convert_to_pdf1a.pdf"];
			{
				// Convert original PDF file to PDFA-1a version.
				NSLog(@"======== PDFACompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfacompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfa_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFAComplianceVersionPDFA1a progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfacompliance_convert_pdfa1a_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfacompliance_convert_pdfa1a_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is not expected to be PDFA-1a compliant as the original did not have accessibility structures.
				NSLog(@"======== PDFACompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfacompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfa_compliance verify:FSPDFAComplianceVersionPDFA1a src_pdf_path:save_pdf_path first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfacompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}

			input_file = [input_path stringByAppendingPathComponent:@"AboutFoxit_Structured.pdf"];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFACompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfacompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfa_compliance verify:FSPDFAComplianceVersionPDFA1a src_pdf_path:input_file first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfacompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			save_pdf_path = [output_directory stringByAppendingPathComponent:@"3_pdfacompliance_convert_to_pdf1a.pdf"];
			{
				// Convert original PDF file to PDFA-1a version.
				NSLog(@"======== PDFACompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfacompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfa_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFAComplianceVersionPDFA1a progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfacompliance_convert_pdfa1a_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfacompliance_convert_pdfa1a_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is expected to be PDFA-1a version.
				NSLog(@"======== PDFACompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfacompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfa_compliance verify:FSPDFAComplianceVersionPDFA1a src_pdf_path:save_pdf_path first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfacompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}
			
			FSPDFXCompliance* pdfx_compliance = [[FSPDFXCompliance alloc] init];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFXCompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfxcompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfx_compliance verify:FSPDFXComplianceVersionPDFX1a src_pdf_path:input_file first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfxcompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			save_pdf_path = [output_directory stringByAppendingPathComponent:@"1_pdfxcompliance_convert_to_pdfx1a.pdf"];
			{
				// Convert original PDF file to PDFX-1a version.
				NSLog(@"======== PDFXCompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfxcompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfx_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFXComplianceVersionPDFX1a view_or_print_condition:FSComplianceEngineViewOrPrintConditionAuto to_convert_rgb_or_lab:NO to_decalibrate_gray_or_cmyk:NO progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfxcompliance_convert_pdfx1a_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfxcompliance_convert_pdfx1a_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is not expected to be PDFX-1a compliant as the original did not have accessibility structures.
				NSLog(@"======== PDFXCompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfxcompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfx_compliance verify:FSPDFXComplianceVersionPDFX1a src_pdf_path:save_pdf_path first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfxcompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}

			input_file = [input_path stringByAppendingPathComponent:@"AboutFoxit_Structured.pdf"];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFXCompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfxcompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfx_compliance verify:FSPDFXComplianceVersionPDFX1a src_pdf_path:input_file first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfxcompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			save_pdf_path = [output_directory stringByAppendingPathComponent:@"3_pdfxcompliance_convert_to_pdfx1a.pdf"];
			{
				// Convert original PDF file to PDFX-1a version.
				NSLog(@"======== PDFXCompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfxcompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfx_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFXComplianceVersionPDFX1a view_or_print_condition:FSComplianceEngineViewOrPrintConditionAuto to_convert_rgb_or_lab:NO to_decalibrate_gray_or_cmyk:NO progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfxcompliance_convert_pdfx1a_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfxcompliance_convert_pdfx1a_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is expected to be PDFX-1a version.
				NSLog(@"======== PDFXCompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfxcompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfx_compliance verify:FSPDFXComplianceVersionPDFX1a src_pdf_path:save_pdf_path first_page_index:0 last_page_index:-1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfxcompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}
			
			FSPDFECompliance* pdfe_compliance = [[FSPDFECompliance alloc] init];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFECompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfecompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfe_compliance verify:input_file first_page_index:0 last_page_index:-1 verify_version:FSPDFEComplianceVersionPDFE1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"0_pdfecompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			save_pdf_path = [output_directory stringByAppendingPathComponent:@"1_pdfecompliance_convert_to_pdfe1.pdf"];
			{
				// Convert original PDF file to PDFE-1a version.
				NSLog(@"======== PDFECompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfecompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfe_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFEComplianceVersionPDFE1  progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfecompliance_convert_pdfe1_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"1_1_pdfecompliance_convert_pdfe1_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is not expected to be PDFE-1a compliant as the original did not have accessibility structures.
				NSLog(@"======== PDFECompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfecompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfe_compliance verify:save_pdf_path first_page_index:0 last_page_index:-1 verify_version:FSPDFEComplianceVersionPDFE1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"1_2_pdfecompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}

			input_file = [input_path stringByAppendingPathComponent:@"AboutFoxit_Structured.pdf"];
			{
				// Verify original PDF file.
				NSLog(@"======== PDFECompliance: Verify before convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfecompliance_verify_before_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info = [pdfe_compliance verify:input_file first_page_index:0 last_page_index:-1 verify_version:FSPDFEComplianceVersionPDFE1 progress_callback:verify_progress_callback];
				[verify_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"2_pdfecompliance_verify_before_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info, result_output_file);
			}

			save_pdf_path = [output_directory stringByAppendingPathComponent:@"3_pdfecompliance_convert_to_pdfe1.pdf"];
			{
				// Convert original PDF file to PDFE-1a version.
				NSLog(@"======== PDFECompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfecompliance_convert_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* convert_result_info = [pdfe_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:FSPDFEComplianceVersionPDFE1 progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfecompliance_convert_pdfe1_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"3_1_pdfecompliance_convert_pdfe1_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}

			{
				// Verify converted result PDF file, which is expected to be PDFE-1a version.
				NSLog(@"======== PDFECompliance: Verify after convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfecompliance_verify_after_convert_progressdata.txt"];
				MyComplianceProgressCallback* verify_progress_callback_2 = [[MyComplianceProgressCallback alloc] init];
				FSResultInformation* verify_result_info_2 = [pdfe_compliance verify:save_pdf_path first_page_index:0 last_page_index:-1 verify_version:FSPDFEComplianceVersionPDFE1 progress_callback:verify_progress_callback_2];
				[verify_progress_callback_2 saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"3_2_pdfecompliance_verify_after_convert_hitdata.txt"];
				OutputPDFAHitData(verify_result_info_2, result_output_file);
			}

			FSPDFCompliance* pdf_compliance = [[FSPDFCompliance alloc] init];
			input_file = [input_path stringByAppendingPathComponent:@"AF_ImageXObject_FormXObject.pdf"];
			{
				// Convert original PDF file to PDF-1.4.
				NSLog(@"======== PDFCompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"4_pdfcompliance_convert_1_4_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				save_pdf_path = [output_directory stringByAppendingPathComponent:@"4_pdfcompliance_convert_to_1_4.pdf"];
				FSResultInformation* convert_result_info = [pdf_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:14 progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"4_pdfcompliance_convert_1_4_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"4_pdfcompliance_convert_1_4_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}
			{
				// Convert original PDF file to PDF-1.7.
				NSLog(@"======== PDFCompliance: Convert ========");
				NSString* progressdata_output_file = [output_directory stringByAppendingPathComponent:@"5_pdfcompliance_convert_1_7_progressdata.txt"];
				MyComplianceProgressCallback* convert_progress_callback = [[MyComplianceProgressCallback alloc] init];
				save_pdf_path = [output_directory stringByAppendingPathComponent:@"5_pdfcompliance_convert_to_1_7.pdf"];
				FSResultInformation* convert_result_info = [pdf_compliance convertPDFFile:input_file saved_pdf_path:save_pdf_path convert_to_version:17 progress_callback:convert_progress_callback];
				[convert_progress_callback saveProgressDataToFile:progressdata_output_file];
				NSString* result_output_file = [output_directory stringByAppendingPathComponent:@"5_pdfcompliance_convert_1_7_fixupdata.txt"];
				OutputPDFAFixupData(convert_result_info, result_output_file);
				result_output_file = [output_directory stringByAppendingPathComponent:@"5_pdfcompliance_convert_1_7_hitdata.txt"];
				OutputPDFAHitData(convert_result_info, result_output_file);
			}


			// Release compliance engine.
			[FSComplianceEngine destroy];
			
			NSLog(@"== End: Compliance demo. ==");
		}
		@catch (NSException *e) {
			NSLog(@"Unknown Exception, %@", e);
			return -1;
		}
	}
	[FSLibrary destroy];
	return 0;
}
