Ghostscript iOS static library

First some version details:

  • Ghostscript version: 9.10
  • CPU Type: armv7 (can be modified easily)
  • iOS Version: 7.0 (can be modified easily)

Ghostscript iOS static library source code contains build script with makefile, architecture details and bunch of executable binaries which are required during compilation.

Lets walk through the build script, which should be copied inside the ghostscript directory and should be run from there. iOS directory and other executable stay at same level as actual ghostscript code.

#Configure is necessary to create tif-config. Also disable cups and sse2
./configure –disable-cups –disable-sse2
#Copy precompiled files for machine cpu
mkdir -p obj/aux
cp ../echogs obj/aux
cp ../genarch obj/aux
cp ../genconf obj/aux
cp ../iOS/MakefileSimulator ./Makefile
cp ../iOS/arch.h ./obj/
#make will fail here so restart after copying file
cp ../mkromfs obj/aux
cp ../mkromfs_0 obj/aux
#remove duplicate symbol object files
rm obj/inobtokn.o
rm obj/gsiodevs.o
ar -crs libgs_x86_release.a obj/*.o
rm -r obj
mkdir -p obj/aux
cp ../echogs obj/aux
cp ../genarch obj/aux
cp ../genconf obj/aux
cp ../iOS/arch.h ./obj/
cp ../iOS/MakefileiOS ./Makefile
cp ../mkromfs obj/aux
cp ../mkromfs_0 obj/aux
ar -crs libgs_arm7_release.a obj/*.o
lipo -output libgsuniversal_release.a -create libgs_arm7_release.a libgs_x86_release.a

Though we have complete make files (which are modified), we need to configure as tiff-config is generated by this command. Compiling cups is not trivial on iOS and SSE2 instructions don’t exist on arm processors hence they are disabled.

After that we copy pre compiled binaries in obj/aux directory. The reason is that we we compile for certain architecture like arm, as we do using specific makefile, we can’t run those executables on the x86 machine. Hence one idea would be compile the complete source as default and then extract these executables to be used later. Here we provide these with the build script.

Now genarch binary generates specific arch according to machine (also explained here), hence we have used the same code to derive architecture specific details by running it on simulator and device. We found it didn’t change hence we use same arch.h for both. Though arm64 may have different architecture details. We copy this pre derived file to obj folder. A modified lib.mak is given as well which can be copied to base folder but we found it unnecessary after copying the arch.h. lib.mak has modification to not generate arch.h.

We copy MakefileSimulator to Makefile inside ghostscript directory. This makefile has modification to use gcc which comes with Xcode for simulator with system root and arch i386 flag to be used. Following has our modifications underlined:

# Define the name of the linker for the final link step.
# Normally this is the same as the C compiler.
# Define the default gcc flags.
GCFLAGS= -Wall -Wstrict-prototypes -Wundef -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings -Wno-strict-aliasing -Wdeclaration-after-statement -fno-builtin -fno-common -DHAVE_STDINT_H=1 -DHAVE_DIRENT_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_INTTYPES_H=1 -DGX_COLOR_INDEX_TYPE=”unsigned long int” –sysroot=/Applications/ -arch i386

Above are the modifications done to makefile generated by configure command.

After running make, it fails on the mkromfs hence we copy correct files to obj/aux in build script and make again. You may see link error but they are just for generating main executable “gs” which we don’t need to worry about. We do same for device as well. Though one thing is different on simulator that we remove couple of object files as otherwise it gives us duplicate symbol issues.

Apart from build script there is Xcode project in GhostscriptiOS folder which has universal library. Example converts the pdf to ps and saves it in documents directory.

Its pretty dirty hack and hopefully I will get time to refine it.

PDF Generation using UIPrintPageRenderer

AirPrint enabled printers accept PDF files and UIPrintPageRenderer prints that content to PDF file. Hence UIPrintPageRenderer can draw to PDF context though there are none public API provided to use this functionality. In this post we will explore this possibility.

There are several StackOverFlow question which talk about how to use private API to achieve pdf generation utilizing UIPrintPageRenderer:

Is there any way to generate PDF file from a XML/HTML template in iOs
Generating a PDF using the new printing stuff in iOS 4.2
How to pretend to be a Printer on iOS like the Apps Save2PDF or Adobe® CreatePDF?

In this post we have employed the methods explained in above stack overflow questions. Following steps lead to PDf generation from simple text, html or a view:

1) Create a Print Formatter: This is basically the content you want to generate PDF with. A print formatter can be an instance of UISimpleTextPrintFormatter, UIMarkupTextPrintFormatter, or UIViewPrintFormatter. These allow to create pdf with simple text, html or a view respectively.

NSString *html = @”<b>Hello <i>World!</i></b>”;

UIMarkupTextPrintFormatter *fmt = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:html];

2) Assign print formatter to UIPrintPageRenderer: Once you have created your print formatter add it to UIPrintPageRenderer at proper index. Method addPrintFormatter:startingAtPageAtIndex: allows any print formatter to be added. One has to pass appropriate index as well.

UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];

[render addPrintFormatter:fmt startingAtPageAtIndex:0];

3) Assign paperRect and printableRect: There is no public API to assign these values hence we need to use setValue:forKey: to assign these values. First we calculate the proper CGRect for these values and then use setValue:forKey: to assign these.

CGRect page;





CGRect printable=CGRectInset( page, 0, 0 );

[render setValue:[NSValue valueWithCGRect:page] forKey:@”paperRect”];

[render setValue:[NSValue valueWithCGRect:printable] forKey:@”printableRect”];

4) Create PDF Context and draw: Now we create PDF context UIGraphicsBeginPDFContextToData and draw using UIPrintPageRenderer.

NSMutableData * pdfData = [NSMutableData data];

UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );

for (NSInteger i=0; i < [render numberOfPages]; i++)



CGRect bounds = UIGraphicsGetPDFContextBounds();

[render drawPageAtIndex:i inRect:bounds];



5) Save PDF file:Once the drawing is complete we can save this in a file in documents directory.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString * pdfFile = [[documentsDirectory stringByAppendingPathComponent:@”test.pdf”] retain];

[pdfData writeToFile:pdfFile atomically:YES];

Source code to generate PDF using UIPrintPageRenderer.



ChartBoost Static Library and Flex Native Extension

During one of the project there was requirement to create a native extension for ChartBoost SDK as explained by Sameer in this post. ChartBoost gives a static library as form of SDK with couple of header files. Using header files in an XCode project I created a static library from which an extension can be easily created using adt. Though the problem was to merge the static library from ChartBoost with the library I created for extension. On top of that the library from ChartBoost had symbols for both armv7 and i386 architecture while for extension we needed only the armv7 architecture.

So the first step was to extract the armv7 library from the ChartBoost static library.

lipo -output libChartBoostarmv7.a -thin armv7 libChartBoost.a

Above commands extracts the armv7 symbols in another static library package. Its very important to specify -thin so we don’t end up with another fat library. We copied libChartBoostarmv7.a and libChartBoostExtension.a in one folder.

mkdir CombinedStaticLib

cp libChartBoostarmv7.a CombinedStaticLib/

cp libChartBoostExtension.a CombinedStaticLib/

Now we extract symbols from both the libraries and combine them using the ar command:

ar -x libChartBoostExtension.a
ar -x libChartBoostarmv7.a
ar -crs libCB.a *.o

libCB.a is the final static library. Using following command one can easily create the ANE file:

Flex_SDK_PATH/bin/adt -package -target ane ../release/ChartBoostExtension.ane extension.xml -swc ChartBoost.swc -platform  iPhone-ARM library.swf libCB.a

I hope you enjoyed some technical process behind the extension we created.


Changing app package for Android in Eclipse

When I started learning to develop Augmented Reality based app on Android I started with Qualcomm’s SDK. As usual I start with sample code provided with any SDK and build upon that. Also that way I am able to check the functionality easily.

Hence I needed to change the name of the package after I built a bit on top of the provided sample app. I found Troubleshooting Resources for Android  useful as it provided the initial directions on how to do that

For example, here’s how you could do this in Eclipse:

  1. Right-click on the package name (src/
  2. Select Refactor > Rename and change the name, for example to
  3. Open the manifest file. Inside the <manifest> tag, change the package name to
  4. Open each of the two Activity files and do Ctrl-Shift-O to add missing import packages, then save each file.
  5. Run the GestureBuilder application on the emulator.

It works well but its not all that you are supposed to do if you are using JNI. There are couple more changes you would need to do:

Java_com_first_second_class_Function( JNIEnv* env, jobject obj)
Change com_first_second to the package name you are changing to. This enables Java would be able to call the native function.

jmethodID functionMethodID = env->GetMethodID(activityClass, “function_name”, “(I)Lcom/first/second/Class;”);
Again change com/first/second to the package name you are changing to. And this enables for native library to call the function in Java.

This should help you get going with package name changes.

Capture image on a Adobe AIR application running on iOS and save to iOS disk

Some of you could ask why this post as it can be achieved using bitmap data and save to camera roll or to app storage using Byte Array?

So to answer if you save bitmap data to camera roll you can not save a reference to that image in your application in case you want to show creations of the user. Only option is to save it in a directory you have access to either in Application Directory or in Document Directory. If you go with that option you have to use byte array to save the image on the disk. It will work fine if you have small images but it wont work well if you have large image or say an image of screen size of iPhone. Read more »

Adobe AIR Native Extension For Chartboost Advertise Network

This is our first post and there are chances of mistakes so please bear with me.

We got a project from a client to create an ios game from a flash action script 3.0 game. He have bought the game code and given us to modify it so it can be played back on iPhone and iPod. This was not a big deal for a company like us. We made the game and it got approved straight away. So we got another project with a new requirement of displaying ads from chartboost. We have read through Adobe forums and find out about the Native Extension so we made a deal with client. Read more »

Compiling FFMPEG for iFrameExtractor

iFrameExtractor is an app for iOS to extract frames from videos using FFMPEG. As FFMPEG supports many video formats one can assume same for iFrameExtractor as well. Though compiling FFMPEG could be painful for iOS. Here is one tip which may help if you are stuck withc compilation.

You may need to add an –extra-ldflags. This points to usr/lib/system directory in your iOS SDK. Following command shows an example which can be easily modified for iOS 5.

./configure –extra-ldflags=-L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/system –disable-bzlib –disable-doc –disable-ffmpeg –disable-ffplay –disable-ffserver –enable-cross-compile –arch=arm –target-os=darwin –cc=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc –as=’gas-preprocessor/ /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc’ –sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk –cpu=cortex-a8 –extra-cflags=’-arch armv7′ –extra-ldflags=’-arch armv7′ –enable-pic