Whitepapers
Download PDF: JetSend Viewer

JetSend Viewer for Windows CE

Introduction

The JetSend Viewer (JetView) for Windows CE is used to view JET files in the Windows CE operating system. The Viewer reads the JET file and renders on the screen the image encodings present in the file. The Viewer also performs view operations like zooming in and out, rotation and flipping of the rendered images.

JetSend Viewer: JetView tool

Fig 1 Shows the JetView tool

Click here to go to Top

Jet File Format

Jet File Format

The jet file has a signature "HPJS" to identify as a valid JetSend material. The jet file has atleast one page or plane. Each page can have number of images. These images will be of RGB, Gray or Mono. Images may be either compressed or uncompressed. The viewer supports JPEG-LSDraft compression technique and RLE compression.

The file format contains four basic sections

  • Document Header:The document header contains information about the entire document, including an offset to the first page.
  • Page Header(1-n, for each page):Contains information about the page, or plane. This includes an offset to the next page, as well as offsets to each child contained within the plane.
  • Child Header (1-n, for each child):Contains information about each child on the plane, including the size of each child.
  • End of file marker:This marks the end of the file.

structure of jet file

The figure shows the structure of 2-page jet file. Each Page has one image

Click here to go to Top

Classes Used For Jet File

Classes Used For Jet File

Jet file is implemented using the class CJet. CJet class will have pointer to each plane or page. Page is implemented using the class CPlane. CPlane class will have pointer to each image. Depending upon the compression technique applied for image and pixel depth of image, appropriate class is used to implement image. If the compression is JPEG-LSDraft then CJpegLsDraft class is used. If image is RLE compressed, then depending upon pixel depth, CRleGray (pixel depth = 8) or CMonoImage (pixel depth = 1) classes are used. If the image is uncompressed, then the class used depends upon pixel depth, CJpegLsDraft (pixel depth = 24) or CRleGray (pixel depth = 8) or CMonoImage (pixel depth = 1).

Click here to go to Top

UI Interface of Jet File

JetView for Windows CE is a Single Document Interface application. So JetView allows opening of a single JET file at a time. The client portion Frame Window is split into two views using CSplitterWnd. One View is image view and the other is page view. The image view displays the image of current page. The image view allows performing operations on the current page. The page view shows thumbnail for all pages. The page view allows the user to manipulate common operations on these pages. The document is implemented by the class CJetViewDoc. The two views are implemented respectively CJetViewView (image view) and CPageView (page view).

Skeleton of JetView

Skeleton of JetView

Click here to go to Top

Features Implemented

  • Open existing jet file
  • Render jet file to screen
  • Create Thumbnails
  • Perform view transformations on displayed page
  • Zoom In
  • Zoom Out
  • Zoom Normal
  • Rotate Left
  • Rotate Right
  • Rotate 180
  • Vertical Flip
  • Horizontal Flip

Open Existing Jet File

JetView allows to open existing jet file through Windows File Open Dialog Box. The document will create a pointer to CJet and calls ReadJet function of CJet. ReadJet function then calls ReadDocHeader to verify whether the jet file is valid e-material and reads each page. CJet will create pointer to each page (CPlane) and reads each page content. CPlane reads plane header and reads each image. CPlane creates pointer to image class depending upon the compression technique and pixel depth of the image. CPlane then calls read routine of image which reads image content and stores this in heap structure of CJet.

Program Flow for Opening a JET file

Serialize function creates a pointer to CJet and calls ReadJet function of CJet.

CJetViewDoc Class

ReadJet calls ReadDocHeader function to verify signature and calls ReadNextPlane function. ReadNextPlane creates pointer to each plane and calls Read routine of CPlane.

CJet Class

Read function reads plane header and calls ReadChild routine which reads image header and creates new image and calls Read routine of CImage.

CPlane Class

Read function reads image content from the file into memory.

CImage Class

Render Jet File

JetView displays image view of current page and thumbnail view for the pages that are visible in the screen. OnDraw function of image view (CJetViewView) calls Display function of CJet. The Display function of the CJet class checks the state of current page. If the current page is decompressed it calls Render function of current page (CPlane). If the page is not yet decompressed it calls AddPage2Thread function. The page view (CPageView) displays thumbnails for the pages. OnDraw function of page view calls GetThumbnail function for each page. After the page has been decompressed, the function returns a handle to the bitmap. If the page has not been decompressed then page view calls AddPage2Thread function for each page.

The information about each page that has to be decompressed is stored in the structure _thread_data. This structure will point to next element of same type. One shared pointer variable g_pHead points to the first node in the list of _thread_data. AddPage2Thread function adds another node to this list.

The list of jobs is maintained in a global queue. Two threads can access the queue. One thread is User Interface thread and the other is a background thread. The background thread can either be a decompress thread, a printing thread or an exporting thread. In order to provide synchronization between these two threads event synchronization is used. In this type of synchronization the WaitForSingleObject call is used. The WaitForSingleObject gives a signal that indicates that the shared variable is not being accessed at that instant.

In this case, g_pHead is the shared variable used for synchronization purpose. Signal is given if g_pHead is to be accessed using the function CreateEvent. So before adding another thread to the list, wait for the signal which indicates g_pHead is not accessed using the WaitForSingleObject call. Then if the thread has not yet been created, create the thread.

There exists only one decompress thread for all pages. Decompress gets called page after page. DecompThread function reads thread data sequentially. It gets first thread structure and calls StartThumbnail function of jet file with plane as parameter. After it finishes decompressing first page, it reads second thread data and so on until all thread data have been read and decompressed.

StartThumbnail function of jet file calls Decompress routine for plane. Decompress function of plane creates a bitmap for the plane size. The plane size depends up on the screen resolution. The e-material has a standard resolution 72000 dpi. The Decompress function of the plane calls Decompress function for each image.

The images exist as either uncompressed or compressed using the JPEG or RLE compression format. HP has provided the decompression technique for JPEG and RLE images. These algorithms have been optimized for performance. For JPEG-LSDraft decompression technique static Lookup tables are used. Each image has its own unique resolution. After decompressing, the StretchBlt function is called to stretch image bitmap to page size at the specified location in page.

Render Jet File

Click here to go to Top

Create Thumbnails

The page view displays thumbnails for the pages. It calls GetThumbnail function of each page to verify whether the thumbnail has been created or not. If the thumbnail for that page has been created then the function returns the bitmap of thumbnail. If the thumbnail is not created, then the GetThumbnail function calls AddPage2Thread function.

The StartThumbnail function of CJet after calling Decompress function of plane calls CreateThumbnail function of plane. The thumbnail size is fixed. 136 pixel width and 136 pixel height. CreateThumbnail function creates a bitmap to this size. Then 8 inches are mapped to 100 pixels in thumbnail. Using approximation the plane data are stretched to this size. The thumbnails are then displayed.

Create Thumbnails

Zoom

The Viewer implements zooming of pages. The different types of zooming implemented are:

  • Zoom In - Zooms into the page. The Viewer allows upto 2 levels of zoom in.
  • Zoom Out - Zooms out of the page. The Viewer allows upto 3 levels of zoom out.
  • Zoom Normal - Zooms to the original size of the page.

Program Flow for the Zoom Operation

The ZoomIn(), ZoomOut() or ZoomNormal() function of the CJet class is called. This function sets the appropriate value of the scale factor.

CJet Class

The SetupNewPage() function is called to set the scroll bars and to fit the page

CJetViewView Class


Image before the zoom in operation

Image before the zoom in operation

Image after the zoom in operation

Image after the zoom in operation

Rotate

The Viewer implements rotating of pages. The different rotations implemented are:

  • RotateRight - Rotates the page by 90 degrees in the clockwise direction
  • RotateLeft - Rotates the page by 90 degrees in the anti-clockwise direction.
  • Rotate180 - Rotates the page by 180 degrees.

The rotation of the page is also performed on the thumbnail view.

Program Flow for the Rotate Operation

The RotateRight(), RotateLeft() or Rotate180() function of the CJet class is called. This function stores information into the JET file indicating that the plane has been rotated.

CJet Class

The RotateRight(), RotateLeft() or Rotate180() function of the CPlane class is called this function performs the rotate operation on the plane.

CPlane Class

The SetupNewPage() function is called to set the scroll bars and to fit the page

CJetViewView Class


Image before the rotate right in operation

Image before the rotate right in operation

Image after the rotate right operation

Image after the rotate right operation

Flip

The Viewer implements flipping of pages. The different flips implemented are:

  • Vertical Flip - Flips the page about the vertical axis.
  • Horizontal Flip - Flips the page about the horizontal axis.

Program Flow for the Flip Operation

The FlipVert() or FlipHorz() function of the CJet class is called. The FlipVert() or FlipHorz() function function stores information into the JET file indicating that the plane has been flipped.

CJet Class

The FlipVert() or FlipHorz() function of the CPlane class is called The FlipVert() or FlipHorz() function performs the flip operation on the plane.

CPlane Class

The SetupNewPage() function is called to set the scroll bars and fit of the page

CJetViewView Class


Image before the vertical flip in operation

Image before the vertical flip in operation

Image after the vertical flip in operation

Click here to go to Top

Restrictions on the H/PC

Memory constraints

In the Hand-held PC (H/PC) the entire memory is split into two parts

  • The object store - This part stores all the files.
  • The program memory - This part is used for processing.

As there is a connection between the object store and the amount of program memory there always has to be a trade-off made between the number of files on the emulator and the amount of memory required to run the programs.

  • Multiple page JET files
  • Color JET files.
  • Uncompressed JET files.

A minimum of 2MB-program memory is required for viewing gray scale JET files and a minimum of 6MB-program memory is required for viewing color JET files.

Programming obstacles faced

  • There is currently no support given by the Microsoft Foundation Classes (MFC) for Compound Documents. The support for compound documents had to be incorporated using the functionality given by SDK.
  • There were certain problems during the debugging of this JetView tool developed for CE. Due to the low programming memory available and large memory requirements for debugging, frequent crashes were encountered during the debugging sessions. This required a number of debugging sessions for tracing out the bugs in the JetView tool.
  • Shared Dlls had to be used because OLE DLLs can not be statically linked in Windows CE. As the Dlls are not statically linked, the Dlls also have to be copied into the H/PC.

Click here to go to Top