Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

decode multiPage rotate tif.zip

5.00/5 (1 vote)
12 Aug 2019CPOL6 min read 5.5K   77  
The decode and encode of multiPage rotate tif.zip

Introduction

This source code shows how to randomly access a certain bitmap from a package (which is made up of lots of mono bitmaps).

The demo package(decode\alphabet.zip) in the attachment which is made up of 26 mono bitmap files (6148 bytes), has been packaged to 5974 bytes, compressed to 3918 bytes.

And this source code can direct access 1 or some or all of them, without decompressing the package file.

Because we wrote in pure C, it can run in other platforms (singlechip, little endian or big endian).

Originally, it was written for singlechip. Reference to why it has to randomly access a certain bmp from a package which is made up of lots of bitmaps.

The source code (MultiPage_tif_decode.c) has been tested by borland c 4.0, visual c 6.0, tinycc 0.9, armCC 5.0, and even keil c51 7.5! Yes, keil c51.exe, version 7.5, not a mistake.

It has been compiled into MultiPage_tif_decode.dll, just 4k bytes. Very small code.

Using the Code

1. MultiPage_tif_decode.dll

It can be compiled by a single C file (decode\multiPage_tif_decode.c). At the front of the file, there are notes for how to compile it from C to DLL.

User can open vc6 project (decode\vc6.dsw) to compile it too.

This DLL exports 3 functions:

1.1. int init_tif_fail(char* file_name, unsigned int* p_bmp_cnt);

It is a constructor, read the zip_comment of user's tif.zip, return the page cnt of it.

1.2. int fini_tif(void);

It is a destructor.

1.3. int tif_get_page_fail(int page_enum, short*p_w,*p_h,*p_rot, long* p_img_ofs,* p_img_byte_cnt, int* p_page_name_leng, ...);

It gets all information of 1 page. After the img_content is read out, it can be handled by the user to do any other thing, such as be rotated, be shown on LCD, be saved in disk....

Image 1

2. Demo for How to Use the DLL

The demo is multiPage_rotate_tif_decode.exe. It can be compiled by a single C file (decode\multiPage_rotate_tif_decode.c). At the front of the file, there are notes for how to compile it from C to EXE.

User can open vc6 project (decode\vc6.dsw) to compile it too.

2.1. Show All bmp

In multiPage_rotate_tif_decode.c\WinMain():

C++
init_tif_fail(file_name,&tif_max_page);
for(i=0;i<tif_max_page;i++)
{tif_get_page_fail(i,
&(p_page->img_width), &(p_page->img_height), &(p_page->rot),
&(p_page->tif_ofs), &(p_page->tif_size), page_name_leng, str_tif_content, g_tif_name);
...
CreateBitmap(p_page->height,p_page->width,1,1, str_bmp_content);
}
fini_tif()

2.2. Handle Menu

The demo has a menu:
Image 2

Save 1 bmp

The "unzip 1..." item, call multiPage_rotate_tif_decode.c\int <a name="get_1_bmp_fail">get_1_bmp_fail</a>(unsigned int i)

C++
if((ret=(tif_get_page_fail(i,
&(p_page->img_width),&(p_page->img_height),&(p_page->rot),
&(p_page->tif_ofs),&(p_page->tif_size), &page_name_leng, str_tif_content,g_tif_name
)) )!=0)
{;}
...
else {g_tif_name[page_name_leng]=0; ret=TIF_SUCCESS; }
Save All bmp

The "unzip all" item, call multiPage_rotate_tif_decode.c\int save_all_bmp_fail(void)

C++
for(i=0;i<tif_max_page;i++)
{err=get_1_bmp_fail(i);
...
}

2.3. set_status_bar

The demo has a status bar. When user selects a page of tif, this demo shows the information (which is got by tif_get_page_fail()) of the page, and shows them:

C++
 if(tif_get_page_fail(i,
	&(p_page->img_width),&(p_page->img_height),&(p_page->rot),
	&(p_page->tif_ofs),&(p_page->tif_size), &page_name_leng,
	NULL,NULL))
	{...}
 else
	wsprintfA(str_bar_status,"w=%d, h=%d, rot=%d, byte_cnt=0x%x, in file [0x%X,0x%X] byte",
		p_page->img_width,p_page->img_height,p_page->rot, p_page->tif_size,
		p_page->tif_ofs,
		p_page->tif_ofs+p_page->tif_size-1);
SetWindowTextA(hEdit,str_bar_status);

3. How to Make a Zip Which Can Be Read by the DLL?

Use multiPage_rotate_tif_encode.exe please. It can be compiled by a single C file (encode\multiPage_rotate_tif_encode.c). At the front of the file, there are notes for how to compile it from C to EXE.

User can open vc6 project (encode\vc6.dsw) to compile it too.

3.1. Usage

In cmd console, input "multiPage_rotate_tif_encode.exe", we would get str_default[] ={"encode.exe [/r=R] [d=dst.zip] <file_1.bmp> [file_2.bmp ... file_n.bmp] or encode.exe [/r=R] [d=dst.zip]

where R = 1...8, means tif's orientation(tag=112h)..."};

e.g.1: We input "multiPage_rotate_tif_encode.exe x.bmp y.bmp", and we would get multi.zip (which is a package include multi.tif, and tif is rotate x and y)

e.g.2: We input "multiPage_rotate_tif_encode.exe /d=xy.zip x.bmp y.bmp", and we would get xy.zip (which is a package include xy.tif, and tif is rotate x and y)

e.g.3: We input "multiPage_rotate_tif_encode.exe /r=1 /d=xy.zip x.bmp y.bmp", and we would get xy.zip (which is a package include xy.tif, and tif is x and y)

e.g.4: We create a tmp.txt, which content is 11 bytes "x.bmp y.bmp". we use it as an @echo_file, input "multiPage_rotate_tif_encode.exe /r=1 /d=xy.zip /s=tmp.txt", and we would get xy.zip (which is a package include xy.tif, and tif is x and y, too)

e.g.5: We input "multiPage_rotate_tif_encode.exe /r=7 /d=..\decode\alphabet.zip /s=echo.txt" will make a alphabet.zip , which is made up of 26 mono bitmap files(6148 bytes),into [..\decode] folder.

3.2. Description

In multiPage_rotate_tif_encode.c\main(), we ...

  • 3.2.1: get_cmd_line(argc,argv);//calculates page_cnt by echo_file, gets rotate and str_tif_name by user's cmdLine
  • 3.2.2: traverse_bmp();//we gets all width and height of bmps(which names are appeared in echo_file)
  • 3.2.3: bmp2tif()
    C++
    {alloc_tif();//malloc(tif_file_size);//the size consult above "tif data structure"
    for(i=0;i<max_bmp;i++)
    	{init_tif_head(i);//setup 8 member(width,height,  depth,rotate, 
        compress,frame_name,  img_ofs,img_size) in tif_frame_header
    	rotate_bmp(i);//read bmp and rotate it
    	}
    }//ifndef LOCAL_SIGNATURE, we can save the memory to tif file now.
  • 3.2.4: tif2zip()
    C++
    unsigned char str_bmp[0x12000];
    {deflate();//compress all tif_frame_header to head_compress_size bytes, into str_bmp[].
     write_zip();//write local_head + central_dir + end_dir + zip_comment into zip file.
    }
    3.2.4.1: zip_comment

    The tif (which has big multi frame_headers) file is too large, can be compressed to a zip file.

To avoid this compressed file waste, the decode.exe lots of time for unzipping, in this c_code, we write some small frame info as zip_comment at the zip file end.

The structure of frame info is struct{u16 w; u16 h; u24 img_ofs; u8 name_length;}, sizeof(it)==8 byte.

The tail of comment is struct{u8 rotate; u8 page_cnt; u16 comment_size;}, sizeof(it)==4 byte.

We write all frame_info and tail into zip_comment, sizeof(zip_comment)==page_cnt*8+4 byte.

In this c_code, zip_file= 0x1e byte(local_head) + zip_tif + 0x2e byte(central_dir) + 0x16 byte(end_dir) + (page_cnt*8+4) byte (zip_comment)

About the example of local_head or central_dir or end_dir, can be seen at multiPage_rotate_tif_encode.c\local_file and cent_dir and end_dir, or multiPage_tif_decode.c\zip_local_dir and zip_cent_dir and zip_end_dir.

Points of Interest

Why Do We Have to Random Access a Certain bmp from a Package Which is Made Up of Lots of Bitmaps

Several years ago...

A client of my boss' software corporation wanted us to show Chinese letters in the panel of his electric_cooker. But the design of his LED_circuit_board was very bad: it showed rows vertically.

Art designer of the client gave us some mono bitmap of letters. We rotated them 90 degrees, translated them into const data in our c_code. Of course, we made index_table to mark every [offset,length,width,height].

After some days, the client wanted to show other letters. So some old letters' definition did NOT exist in code, and some new definitions would appear. We handled the code conflict for several hours.

After some days, the client came into our workshop, wanted to see some temporary effects of his many ideas. He changed his mind, and changed his Chinese letters so many times. I could not refuse, because my boss stood near him.

The client was very satisfied with my boss' corporation, he showed his next production (electric_kettle) to my boss. The LED_circuit_board showed rows vertically, in the OTHER direction.

So, I decided to store the bitmaps (after rotated) in the resource file, to separate the code and interface. And, that's the reason of the c_code above.

History

  • 5th August, 2019: Can be compiled with bc4.5 and keil c51 7.5. Submitted
  • May, 2016: Can be compiled with vc6.0 and armCC

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)