Solved

Jpeg header in c

Posted on 2010-09-01
28
908 Views
Last Modified: 2012-05-10
I want to save an image  file as jpeg file using ansi c.
Can I get the header data structure in c and way to write/ store the jpeg file?
0
Comment
Question by:gprconsultants
  • 14
  • 10
  • +2
28 Comments
 
LVL 53

Accepted Solution

by:
Infinity08 earned 250 total points
ID: 33578264
Have a look at libjpeg :

        http://www.ijg.org/
0
 
LVL 30

Assisted Solution

by:Zoppo
Zoppo earned 250 total points
ID: 33578273
Hi gprconsultants,

you could use 'libjpeg' which is a free library written in C to encode, decode and modify JPEGs.

For more info take a look here:

http://en.wikipedia.org/wiki/Libjpeg
http://www.ijg.org/

Hope that helps,

ZOPPO
0
 

Author Comment

by:gprconsultants
ID: 33596065
Hello all
I want to convert bmp file to jpeg.
I read bmp file applied dct . but dont know how to store it as jpeg

Thank you
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33597369
>> I want to convert bmp file to jpeg.

That's really a different question than what you asked originally, but have a look at the imagemagick library for your image conversion needs :

        http://www.imagemagick.org/script/index.php
0
 

Expert Comment

by:prince_m
ID: 33634821
0
 

Author Comment

by:gprconsultants
ID: 33717309
Hello All,
I have written the code for bmp to jpeg image conversion. But not getting the corect resultant image.
I am attaching the image with code here.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "jtypes.h"

#include "jglobals.h"

#include "jtables.h"

#include  <conio.h>

#define N 8

//bitstring bitcode;



int startr,startc;

typedef struct bmpinfo

{

unsigned long size;

long width;

long height;

unsigned short planes;

unsigned short bitcount;

unsigned long compression;

unsigned long imagesize;

long xres;

long yres;

unsigned long colours;

unsigned long impcolors;

} BITMAPINFOHEADER;





#pragma pack(1)

typedef struct bmpfile

{

//unsigned short type;

unsigned long size;

unsigned short reserved1;

unsigned short reserved2;

unsigned long offset;

}BITMAPFILEHEADER;



int R[64][64],B[64][64],G[64][64];

  BITMAPFILEHEADER bmfh;

  BITMAPINFOHEADER bmih;

unsigned char s=0;

void write_APP0info()

//Nothing to overwrite for APP0info

{

	writeword(APP0info.marker);

	writeword(APP0info.length);

	writebyte('J');

	writebyte('F');

	writebyte('I');

	writebyte('F');

	writebyte(0);

	writebyte(APP0info.versionhi);

	writebyte(APP0info.versionlo);

	writebyte(APP0info.xyunits);

	writeword(APP0info.xdensity);

	writeword(APP0info.ydensity);

	writebyte(APP0info.thumbnwidth);

	writebyte(APP0info.thumbnheight);

}



void write_SOF0info()

// We should overwrite width and height

{

	writeword(SOF0info.marker);

	writeword(SOF0info.length);

	writebyte(SOF0info.precision);

	writeword(SOF0info.height);

	writeword(SOF0info.width);

	writebyte(SOF0info.nrofcomponents);

	writebyte(SOF0info.IdY);

	writebyte(SOF0info.HVY);

	writebyte(SOF0info.QTY);

	writebyte(SOF0info.IdCb);

	writebyte(SOF0info.HVCb);

	writebyte(SOF0info.QTCb);

	writebyte(SOF0info.IdCr);

	writebyte(SOF0info.HVCr);

	writebyte(SOF0info.QTCr);

}



void write_DQTinfo()

{

	BYTE i;



	writeword(DQTinfo.marker);

	writeword(DQTinfo.length);

	writebyte(DQTinfo.QTYinfo);

	for (i=0; i<64; i++)

		writebyte(DQTinfo.Ytable[i]);

	writebyte(DQTinfo.QTCbinfo);

	for (i=0; i<64; i++)

		writebyte(DQTinfo.Cbtable[i]);

}



void set_quant_table(BYTE *basic_table, BYTE scale_factor, BYTE *newtable)

// Set quantization table and zigzag reorder it

{

	BYTE i;

	long temp;



	for (i=0; i<64; i++) 

	{

		temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;

		// limit the values to the valid range

		if (temp <= 0L) 

			temp = 1L;

		if (temp > 255L) 

			temp = 255L; 

		newtable[zigzag[i]] = (BYTE) temp;

	}

}



void set_DQTinfo()

{

	BYTE scalefactor = 50;// scalefactor controls the visual quality of the image

	// the smaller is the better image we'll get, and the smaller

	// compression we'll achieve

	DQTinfo.marker = 0xFFDB;

	DQTinfo.length = 132;

	DQTinfo.QTYinfo = 0;

	DQTinfo.QTCbinfo = 1	;

	set_quant_table(std_luminance_qt, scalefactor, DQTinfo.Ytable);

	set_quant_table(std_chrominance_qt, scalefactor, DQTinfo.Cbtable);

}



void write_DHTinfo()

{

	BYTE i;

	

	writeword(DHTinfo.marker);

	writeword(DHTinfo.length);

	writebyte(DHTinfo.HTYDCinfo);

	for (i=0; i<16; i++)  

		writebyte(DHTinfo.YDC_nrcodes[i]);

	for (i=0; i<12; i++) 

		writebyte(DHTinfo.YDC_values[i]);

	writebyte(DHTinfo.HTYACinfo);

	for (i=0; i<16; i++)

		writebyte(DHTinfo.YAC_nrcodes[i]);

	for (i=0; i<162; i++) 

		writebyte(DHTinfo.YAC_values[i]);

	writebyte(DHTinfo.HTCbDCinfo);

	for (i=0; i<16; i++) 

		writebyte(DHTinfo.CbDC_nrcodes[i]);

	for (i=0; i<12; i++)

		writebyte(DHTinfo.CbDC_values[i]);

	writebyte(DHTinfo.HTCbACinfo);

	for (i=0; i<16; i++)

		writebyte(DHTinfo.CbAC_nrcodes[i]);

	for (i=0; i<162; i++)

		writebyte(DHTinfo.CbAC_values[i]);

}



void set_DHTinfo()

{

	BYTE i;

	

	// fill the DHTinfo structure [get the values from the standard Huffman tables]

	DHTinfo.marker = 0xFFC4;

	DHTinfo.length = 0x01A2;

	DHTinfo.HTYDCinfo = 0;

	for (i=0; i<16; i++)

		DHTinfo.YDC_nrcodes[i] = std_dc_luminance_nrcodes[i+1];

	for (i=0; i<12; i++)

		DHTinfo.YDC_values[i] = std_dc_luminance_values[i];

	

	DHTinfo.HTYACinfo = 0x10;

	for (i=0; i<16; i++)

		DHTinfo.YAC_nrcodes[i] = std_ac_luminance_nrcodes[i+1];

	for (i=0; i<162; i++)

		DHTinfo.YAC_values[i] = std_ac_luminance_values[i];

	

	DHTinfo.HTCbDCinfo = 1;

	for (i=0; i<16; i++)

		DHTinfo.CbDC_nrcodes[i] = std_dc_chrominance_nrcodes[i+1];

	for (i=0; i<12; i++)

		DHTinfo.CbDC_values[i] = std_dc_chrominance_values[i];

	

	DHTinfo.HTCbACinfo = 0x11;

	for (i=0; i<16; i++)

		DHTinfo.CbAC_nrcodes[i] = std_ac_chrominance_nrcodes[i+1];

	for (i=0; i<162; i++)

		DHTinfo.CbAC_values[i] = std_ac_chrominance_values[i];

}



void write_SOSinfo()

//Nothing to overwrite for SOSinfo

{

	writeword(SOSinfo.marker);

	writeword(SOSinfo.length);

	writebyte(SOSinfo.nrofcomponents);

	writebyte(SOSinfo.IdY);

	writebyte(SOSinfo.HTY);

	writebyte(SOSinfo.IdCb);

	writebyte(SOSinfo.HTCb);

	writebyte(SOSinfo.IdCr);

	writebyte(SOSinfo.HTCr);

	writebyte(SOSinfo.Ss);

	writebyte(SOSinfo.Se);

	writebyte(SOSinfo.Bf);

}



void write_comment(BYTE *comment)

{

	WORD i, length;

	

	writeword(0xFFFE); // The COM marker

	length = strlen((const char *)comment);

	writeword(length + 2);

	for (i=0; i<length; i++) 

		writebyte(comment[i]);

}



void writebits(bitstring bs)

// A portable version; it should be done in assembler

{

	long int value;

	SBYTE posval;// bit position in the bitstring we read, should be <=15 and >=0



	value = bs.value;

	posval = bs.length - 1;

	while (posval >= 0)

	{

		if (value & mask[posval])

			bytenew |= mask[bytepos];

		posval--;

		bytepos--;

		if (bytepos < 0)

		{

			// write it

			if (bytenew == 0xFF)

			{

				// special case

				writebyte(0xFF);

				writebyte(0);

			}

			else

				writebyte(bytenew);

				printf(" %hd ",bytenew);

			// reinit

			bytepos = 7;

			bytenew = 0;

		}

	}

}



void compute_Huffman_table(BYTE *nrcodes, BYTE *std_table, bitstring *HT)

{

	BYTE k,j;

	BYTE pos_in_table;

	WORD codevalue;

	

	codevalue = 0; 

	pos_in_table = 0;

	for (k=1; k<=16; k++)

	{

		for (j=1; j<=nrcodes[k]; j++) 

		{

			HT[std_table[pos_in_table]].value = codevalue;

			HT[std_table[pos_in_table]].length = k;

			pos_in_table++;

			codevalue++;

		}

		

		codevalue <<= 1;

	}

}



void init_Huffman_tables()

{

	// Compute the Huffman tables used for encoding

	compute_Huffman_table(std_dc_luminance_nrcodes, std_dc_luminance_values, YDC_HT);

	compute_Huffman_table(std_ac_luminance_nrcodes, std_ac_luminance_values, YAC_HT);

	compute_Huffman_table(std_dc_chrominance_nrcodes, std_dc_chrominance_values, CbDC_HT);

	compute_Huffman_table(std_ac_chrominance_nrcodes, std_ac_chrominance_values, CbAC_HT);

}



void exitmessage(char *error_message)

{

	printf("%s\n",error_message);

	exit(EXIT_FAILURE);

}

int find_cat(long int num)

{

if(num==0) return 0;

 if(num ==-1 || num==1)

   return 1;

    if((num >=-3 && num<=-2)||(num>=2 && num<=3))

   return 2;

    if((num >=-7 && num<=-4)||(num>=4 && num<=7))

   return 3;

    if((num >=-15 && num<=-8)||(num>=8 && num<=15))

   return 4;

    if((num >=-31 && num<=-16)||(num>=16 && num<=31))

   return 5;

 if((num >=-63 && num<=-32)||(num>=32 && num<=63))

   return 6;

if((num >=-127 && num<=-64)||(num>=64 && num<=127))

   return 7;

 if((num >=-255 && num<=-128)||(num>=128 && num<=255))

   return 8;

    if((num >=-511 && num<=-256)||(num>=256 && num<=511))

   return 9;

    if((num >=-1023 && num<=-512)||(num>=512 && num<=1032))

   return 10;

    if((num >=-2047 && num<=-1024)||(num>=1024 && num<=2047))

   return 11;

    if((num >=-4095 && num<=-2048)||(num>=2048 && num<=4095))

   return 12;

    if((num >=-8191 && num<=-4096)||(num>=4096 && num<=8191))

   return 13;

    if((num >=-16383 && num<=-8192)||(num>=8192 && num<=16383))

   return 14;

    if((num >=-32767 && num<=-16384)||(num>=16384 && num<=32767))

   return 15;

}



long int nrupper(long int num)

{   int ch1=find_cat(num);

    if(ch1==1)

      return 2;



    if(ch1==2)

      return 4;

   if(ch1==3)

      return 8;

   if(ch1==4)

      return 16;

    if(ch1==5)

      return 32;

    if(ch1==6)

      return 64;

    if(ch1==7)

      return 128;

if(ch1==8)

      return 256;

if(ch1==9)

      return 512;

if(ch1==10)

      return 1024;

if(ch1==11)

      return 2048;

if(ch1==12)

      return 4096;

if(ch1==13)

      return 8192;

if(ch1==14)

      return 16384;

      if(ch1==15)

      return 32768;

}

void find_value(double num)

{        bitstring bs2;

	bs2.length=find_cat(num);

	if(num>0)

	{

	bs2.value=(WORD)num;

//		if(find_cat(num)==4 && s==1)

 //	printf("\n num=%ld       result=%ld ",(long int)num,(long int)bs2.value);

	}

	else

	{

	bs2.value=(WORD)(nrupper(num)-1+num);

   //	if(find_cat(num)==4 && s==1)

    //	printf("\n num=%ld       result=%ld",(long int)num,(long int)bs2.value);

	}

	writebits(bs2);

}

void set_numbers_category_and_bitcode()

{

/*	SDWORD nr;

	SDWORD nrlower, nrupper;

	BYTE cat;

  */



    /*	category_alloc = (BYTE *)malloc(4096*sizeof(BYTE));

	if (category_alloc == NULL)

		exitmessage("Not enough memory.");

	else

       {	printf("\n allocated 8192");

	 // exit(0);

       }*/



	//allow negative subscripts

 //	category = category_alloc + 2048;



/*	bitcode_alloc=(bitstring *)malloc(4096*sizeof(bitstring));

	if (bitcode_alloc==NULL)

		exitmessage("Not enough memory.");



	bitcode = bitcode_alloc + 2048;



	nrlower = 1;

	nrupper = 2;

	for (cat=1; cat<=11; cat++)

	{

		//Positive numbers

		for (nr=nrlower; nr<nrupper; nr++)

		{

			//category[nr] = cat;

			bitcode[nr].length = cat;

			bitcode[nr].value = (WORD)nr;

		}

		//Negative numbers

		for (nr=-(nrupper-1); nr<=-nrlower; nr++)

		{

			category[nr] = cat;

			bitcode[nr].length = cat;

			bitcode[nr].value = (WORD)(nrupper-1+nr);

		}



		nrlower <<= 1;

		nrupper <<= 1;

	}       */



}



void precalculate_YCbCr_tables()

{

	WORD R,G,B;



	for (R=0; R<256; R++)

	{

		YRtab[R] = (SDWORD)(65536*0.299+0.5)*R;

		CbRtab[R] = (SDWORD)(65536*-0.16874+0.5)*R;

		CrRtab[R] = (SDWORD)(32768)*R;

	}

	for (G=0; G<256; G++)

	{

		YGtab[G] = (SDWORD)(65536*0.587+0.5)*G;

		CbGtab[G] = (SDWORD)(65536*-0.33126+0.5)*G;

		CrGtab[G] = (SDWORD)(65536*-0.41869+0.5)*G;

	}

	for (B=0; B<256; B++)

	{

		YBtab[B] = (SDWORD)(65536*0.114+0.5)*B;

		CbBtab[B] = (SDWORD)(32768)*B;

		CrBtab[B] = (SDWORD)(65536*-0.08131+0.5)*B;

	}

}

// Using a bit modified form of the FDCT routine from IJG's C source:

// Forward DCT routine idea taken from Independent JPEG Group's C source for

// JPEG encoders/decoders



/* For float AA&N IDCT method, divisors are equal to quantization

   coefficients scaled by scalefactor[row]*scalefactor[col], where

   scalefactor[0] = 1

   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7

   We apply a further scale factor of 8.

   What's actually stored is 1/divisor so that the inner loop can

   use a multiplication rather than a division. */

void prepare_quant_tables()

{

	double aanscalefactor[8] = {1.0, 1.387039845, 1.306562965, 1.175875602,

		1.0, 0.785694958, 0.541196100, 0.275899379};

	BYTE row, col;

	BYTE i = 0;



	for (row = 0; row < 8; row++)

	{

		for (col = 0; col < 8; col++)

		{

			fdtbl_Y[i] = (float) (1.0 / ((double) DQTinfo.Ytable[zigzag[i]] *

				aanscalefactor[row] * aanscalefactor[col] * 8.0));

			fdtbl_Cb[i] = (float) (1.0 / ((double) DQTinfo.Cbtable[zigzag[i]] *

				aanscalefactor[row] * aanscalefactor[col] * 8.0));

			i++;

		}

	}

}



void fdct_and_quantization(SBYTE *data, float *fdtbl, SWORD *outdata)

{

	float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

	float tmp10, tmp11, tmp12, tmp13;

	float z1, z2, z3, z4, z5, z11, z13;

	float *dataptr;

	float datafloat[64];

	float temp;

	SBYTE ctr;

	BYTE i;



	for (i=0; i<64; i++)

		datafloat[i] = data[i];



	/* Pass 1: process rows. */

	dataptr = datafloat;

	for (ctr = 7; ctr >= 0; ctr--)

	{

		tmp0 = dataptr[0] + dataptr[7];

		tmp7 = dataptr[0] - dataptr[7];

		tmp1 = dataptr[1] + dataptr[6];

		tmp6 = dataptr[1] - dataptr[6];

		tmp2 = dataptr[2] + dataptr[5];

		tmp5 = dataptr[2] - dataptr[5];

		tmp3 = dataptr[3] + dataptr[4];

		tmp4 = dataptr[3] - dataptr[4];



		/* Even part */



		tmp10 = tmp0 + tmp3;	/* phase 2 */

		tmp13 = tmp0 - tmp3;

		tmp11 = tmp1 + tmp2;

		tmp12 = tmp1 - tmp2;



		dataptr[0] = tmp10 + tmp11; /* phase 3 */

		dataptr[4] = tmp10 - tmp11;



		z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */

		dataptr[2] = tmp13 + z1;	/* phase 5 */

		dataptr[6] = tmp13 - z1;



		/* Odd part */



		tmp10 = tmp4 + tmp5;	/* phase 2 */

		tmp11 = tmp5 + tmp6;

		tmp12 = tmp6 + tmp7;



		/* The rotator is modified from fig 4-8 to avoid extra negations. */

		z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */

		z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */

		z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */

		z3 = tmp11 * ((float) 0.707106781); /* c4 */



		z11 = tmp7 + z3;		/* phase 5 */

		z13 = tmp7 - z3;



		dataptr[5] = z13 + z2;	/* phase 6 */

		dataptr[3] = z13 - z2;

		dataptr[1] = z11 + z4;

		dataptr[7] = z11 - z4;



		dataptr += 8;		/* advance pointer to next row */

	}



  /* Pass 2: process columns. */



	dataptr = datafloat;

	for (ctr = 7; ctr >= 0; ctr--)

	{

		tmp0 = dataptr[0] + dataptr[56];

		tmp7 = dataptr[0] - dataptr[56];

		tmp1 = dataptr[8] + dataptr[48];

		tmp6 = dataptr[8] - dataptr[48];

		tmp2 = dataptr[16] + dataptr[40];

		tmp5 = dataptr[16] - dataptr[40];

		tmp3 = dataptr[24] + dataptr[32];

		tmp4 = dataptr[24] - dataptr[32];



		/* Even part */



		tmp10 = tmp0 + tmp3;	/* phase 2 */

		tmp13 = tmp0 - tmp3;

		tmp11 = tmp1 + tmp2;

		tmp12 = tmp1 - tmp2;



		dataptr[0] = tmp10 + tmp11; /* phase 3 */

		dataptr[32] = tmp10 - tmp11;



		z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */

		dataptr[16] = tmp13 + z1; /* phase 5 */

		dataptr[48] = tmp13 - z1;



		/* Odd part */



		tmp10 = tmp4 + tmp5;	/* phase 2 */

		tmp11 = tmp5 + tmp6;

		tmp12 = tmp6 + tmp7;



		/* The rotator is modified from fig 4-8 to avoid extra negations. */

		z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */

		z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */

		z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */

		z3 = tmp11 * ((float) 0.707106781); /* c4 */



		z11 = tmp7 + z3;		/* phase 5 */

		z13 = tmp7 - z3;



		dataptr[40] = z13 + z2; /* phase 6 */

		dataptr[24] = z13 - z2;

		dataptr[8] = z11 + z4;

		dataptr[56] = z11 - z4;



		dataptr++;			/* advance pointer to next column */

	}



	/* Quantize/descale the coefficients, and store into output array */

	for (i = 0; i < 64; i++)

	{

		/* Apply the quantization and scaling factor */

		temp = datafloat[i] * fdtbl[i];



	/* Round to nearest integer.

	   Since C does not specify the direction of rounding for negative

	   quotients, we have to force the dividend positive for portability.

	   The maximum coefficient size is +-16K (for 12-bit data), so this

	   code should work for either 16-bit or 32-bit ints.

	*/

		outdata[i] = (SWORD) ((SWORD)(temp + 16384.5) - 16384);



//		printf("  %hd ",outdata[i]);

	}

}



void process_DU(SBYTE *ComponentDU,float *fdtbl,SWORD *DC,

				bitstring *HTDC,bitstring *HTAC)

{

	bitstring EOB = HTAC[0x00];

	bitstring M16zeroes = HTAC[0xF0];

	BYTE i;

	BYTE startpos;

	BYTE end0pos;

	BYTE nrzeroes;

	BYTE nrmarker;

	SWORD Diff;



	fdct_and_quantization(ComponentDU, fdtbl, DU_DCT);



	// zigzag reorder

	for (i=0; i<64; i++)

		DU[zigzag[i]]=DU_DCT[i];



	// Encode DC

	Diff = DU[0] - *DC;

	*DC = DU[0];



	if (Diff == 0)

		writebits(HTDC[0]); //Diff might be 0

	else

	{



		writebits(HTDC[find_cat(Diff)]);

	      //	writebits(bitcode[Diff]);

	      find_value(Diff);

	}



	// Encode ACs

	for (end0pos=63; (end0pos>0)&&(DU[end0pos]==0); end0pos--) ;

	//end0pos = first element in reverse order != 0



	i = 1;

	while (i <= end0pos)

	{

		startpos = i;

		for (; (DU[i]==0) && (i<=end0pos); i++) ;

		nrzeroes = i - startpos;

		if (nrzeroes >= 16)

		{

			for (nrmarker=1; nrmarker<=nrzeroes/16; nrmarker++)

				writebits(M16zeroes);

			nrzeroes = nrzeroes%16;

		}

		writebits(HTAC[nrzeroes*16+find_cat(DU[i])]);

	       //	writebits(bitcode[DU[i]]);

	       find_value(DU[i]);

		i++;

	}



	 if (end0pos != 63)

	       writebits(EOB);

}



/*void load_data_units_from_RGB_buffer(WORD xpos, WORD ypos)

{

	BYTE x, y;

	BYTE pos = 0;

	DWORD location;

	BYTE R, G, B;



	location = ypos * width + xpos;

	for (y=0; y<8; y++)

	{

		for (x=0; x<8; x++)

		{

			R = RGB_buffer[location].R;

			G = RGB_buffer[location].G;

			B = RGB_buffer[location].B;

			// convert to YCbCr

			YDU[pos] = Y(R,G,B);

			CbDU[pos] = Cb(R,G,B);

			CrDU[pos] = Cr(R,G,B);

			location++;

			pos++;

		}

		location += width - 8;

	}

}

*/

void main_encoder()

{

	SWORD DCY = 0, DCCb = 0, DCCr = 0;

	 int Loop, i,j,l,m,p,q,count,k;

//	 unsigned char k;

		BYTE pos=0;  int row,col;



    printf("\n read pixel matrix");

for(row=0;row<bmih.height;row+=N)

{

      for(col=0;col<bmih.width;col+=N)

	   {

	startr=row;startc=col; pos=0;

	for(i=0,l=startr;i<N;i++,l++)

	{

	    for(j=0,k=startc;j<N;j++,k++)

	     {

		YDU[pos]=(SBYTE)R[l][k];

		CbDU[pos]=(SBYTE)G[l][k];

		CrDU[pos]=(SBYTE)B[l][k];

		pos++;

	     }

	 }

		process_DU(YDU, fdtbl_Y, &DCY, YDC_HT, YAC_HT);



		process_DU(CbDU, fdtbl_Cb, &DCCb, CbDC_HT, CbAC_HT);

		process_DU(CrDU, fdtbl_Cb, &DCCr, CbDC_HT, CbAC_HT);



       }

}

printf("\n Processed and written data successfully");



	/*for (ypos=0; ypos<height; ypos+=8)

	{

		for (xpos=0; xpos<width; xpos+=8)

		{

			load_data_units_from_RGB_buffer(xpos, ypos);



			process_DU(YDU, fdtbl_Y, &DCY, YDC_HT, YAC_HT);

			process_DU(CbDU, fdtbl_Cb, &DCCb, CbDC_HT, CbAC_HT);

			process_DU(CrDU, fdtbl_Cb, &DCCr, CbDC_HT, CbAC_HT);

		}

	}*/

}







void init_all()

{

	set_DQTinfo();

	set_DHTinfo();

	init_Huffman_tables();

	set_numbers_category_and_bitcode();

	precalculate_YCbCr_tables();

	prepare_quant_tables();

}



void main()

{

	  FILE *ImageFile;//*fp_jpeg_stream;

	 unsigned char c1; char magic[2];

	  int Loop, i,j,k,l,m,p,q,count;

	       unsigned char Y1,Cb1,Cr1;

	WORD width_original,height_original;



	BYTE len_filename;



	bitstring fillbits;

	clrscr();

	 if((ImageFile = fopen("lena2.bmp", "rb")) == NULL)

    {

    printf("Could not open file for reading");

    exit(0);



    }

    fread(magic,2,1,ImageFile);

    fread(&bmfh, sizeof(BITMAPFILEHEADER), 1, ImageFile);

    fread(&bmih, sizeof(BITMAPINFOHEADER), 1, ImageFile);

    width=bmih.width; height=bmih.height;

//   a=A;

//   fseek(ImageFile,0,SEEK_CUR);

     i=0;k=0;l=0;m=0;p=0;q=0;count=0;



     printf("\n READING PIXEL MATRIX");

    for(Loop = 0; Loop < ((bmih.height * bmih.width) * 3); Loop += 1)

      { fread(&c1, sizeof(unsigned char), 1,ImageFile);

    red:   if(count==0)

      {

      if(k<64)  R[i][k++]=c1;



    else

      {

	i++; k=0;

	R[i][k++]=c1;

      }

      } //if

       else if (count==1)

       {

       if(m<64)   G[l][m++]=c1;

       else

     {

      l++; m=0;

      G[l][m++]=c1;

     }

       }//else if

       else if(count==2)

       {

     if(q<64)   B[p][q++]=c1;

       else

     {

      p++; q=0;

      B[p][q++]=c1;

     }

       }//else if

       else { count=0; goto red; }

       count++;

    }



    fclose(ImageFile);

for(i=0;i<64;i++)

 {

for(j=0;j<64;j++)

{

Y1=((unsigned char)(0.299* R [i][j]+ 0.587 * G[i][j] + 0.114 * B[i][j]));

//Y1=Y(R[i][j],G[i][j],B[i][j]);

Cb1=((unsigned char)(- 0.1687* R[i][j]- 0.3313 *  G[i][j] + 0.5 * B[i][j] + 128));

//Cb1=Cb(R[i][j],G[i][j],B[i][j]);

Cr1=((unsigned char)(0.5 * R[i][j] - 0.4187 * G[i][j] - 0.0813 * B[i][j] + 128));

//Cr1=Cr(R[i][j],G[i][j],B[i][j]);

R[i][j]=Y1;

G[i][j]=Cb1;

B[i][j]=Cr1;

}

}



	fp_jpeg_stream = fopen("new_image.jpg","wb");

	init_all();

	printf("\n Setting width n height");

	SOF0info.width = bmih.width;

	SOF0info.height = bmih.height;



	writeword(0xFFD8); // SOI

	write_APP0info();

	// write_comment("Cris made this JPEG with his own encoder");

	write_DQTinfo();

	write_SOF0info();

	write_DHTinfo();

	write_SOSinfo();



	// init global variables

	bytenew = 0; // current byte

	bytepos = 7; // bit position in this byte

	main_encoder();



	// Do the bit alignment of the EOI marker

	if (bytepos >= 0)

	{

		fillbits.length = bytepos + 1;

		fillbits.value = (1<<(bytepos+1)) - 1;

		writebits(fillbits);

	}

	writeword(0xFFD9); // EOI



	//      free(RGB_buffer);

       //	free(category_alloc);

       //	free(bitcode_alloc);

	fclose(fp_jpeg_stream);

printf("\n Written and saved the file");

}

Open in new window

0
 

Author Comment

by:gprconsultants
ID: 33717345
I am working on 64x64 bmp image with depth=24 bits.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33717477
Could you post the original image, as well as the converted image you get ?
0
 

Author Comment

by:gprconsultants
ID: 33717622
Hello ,
Original image. Also I have not posted the header files. Do i send it?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33717627
Anything you have that you think might be useful :)
0
 

Author Comment

by:gprconsultants
ID: 33717636
sorry.
It has not added
lena2.bmp
NEW-IMAG.JPG
0
 

Author Comment

by:gprconsultants
ID: 33717707
header files. Can I get the solution?
JGLOBALS.H
JTABLES.H
JTYPES.H
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33724883
Your code is difficult to read, so I'll base myself on the images instead.

The image looks like it's flipped vertically. That should be relatively easy to fix (start filling from the other side of the image).

The colours look like they're inverted, and smoothed. So there are probably conversion as well as rounding errors somewhere.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:gprconsultants
ID: 33724984
can i comment out the code so that it becomes readable.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33725049
>> can i comment out the code so that it becomes readable.

To make the code more readable, you'd at the very least need to get rid of all magic values, and meaningless symbol names. It would also be good to modularize the code into meaningful (properly named) functions. It would also help a lot if the code was properly indented.



While quickly scanning the code (without looking at the details), my eye fell on this :

>> R[i][j]=Y1;
>> G[i][j]=Cb1;
>> B[i][j]=Cr1;

This seems to suggest that this is using YCbCr, as if it were RGB. That could explain the wrong colours.
0
 

Author Comment

by:gprconsultants
ID: 33725123
Actually I have converted  R,,G,B into Y,Cb,Cr and every byte is written (saved) back to R,G,B matrices. So that i will save the space. I think the error is in rounding. But still I am not getting probable reason/statement from the code.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33725307
>> and every byte is written (saved) back to R,G,B matrices.

Ok.


>> But still I am not getting probable reason/statement from the code.

I'd start by tracking down the easy part : the fact that the image is mirrored vertically.
0
 

Author Comment

by:gprconsultants
ID: 33725325
the steps are:
1)  Read 24 bit bmp file and converted into R,G,B pixel matrices
2) R[][],G[][],B[][] are converted to Y,Cb,Cr and then stored back in the three matrices so that R[][] stores
    Y, G[][] stores Cb and so on
3) Then opened the file .jpeg which is to be written
4) Stored the header information
5) Called main_encoder()
6) in main_encoder, conveted each data unit of 8x8 block into array and then a call is made for process_DU for each 64 byte array of Y,Cb,cR
7)In Process_DU, performed DCT and Quantization using IJG's DCT Routine and Written the bitstring for the data to file
8) All the function SET_DHTinfo,SET_DQTinfo sets the value for header and WRITE_... writes the header.
9) bitswise dat is written using writebits() function.
10) debugging is done by placing printf() wherever necessory.

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33725820
The vertical mirroring is indeed because you're processing the BMP data in the wrong order. The BMP data starts in the lower left corner of the image (the first row is the bottom row of the image), so the loop in the main_encoder function has to be changed to :

        for (row = bmih.height - 1; row >= 0; row -= N)

instead of :

>> for(row=0;row<bmih.height;row+=N)

and :

        for (i = 0, l = startr; i < N; i++, l--)

instead of :

>>       for(i=0,l=startr;i<N;i++,l++)
0
 

Author Comment

by:gprconsultants
ID: 33728505
Thanks a lot. Now the vertical mirroring problem is solved. The next problem may be because of color space transformation or some mistake might be there in writing the header.
0
 

Author Comment

by:gprconsultants
ID: 33731948
After some modiications I got the image attched herewith

NEW-IMAG.JPG
0
 

Author Comment

by:gprconsultants
ID: 33731970
Again thank you for your kind and prompt help. I am trying to solve the problem.
0
 

Author Comment

by:gprconsultants
ID: 33733496
Hello Infinity08,
I got the solution. I have atteched the image here. Thanks.

NEW-IMAG.JPG
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33736535
Great. Sorry I couldn't get back earlier. I haven't had the chance.

So, what was the problem with the colours ?
0
 

Author Comment

by:gprconsultants
ID: 33752992
the problem was in the redaing of RGB color. Actually in Bitmap the data is stored as B,G,R and as R,G,B.
I just changed the sequence and it worked.
Thanks.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33753130
Ah. Nice find :)
0
 
LVL 40

Expert Comment

by:evilrix
ID: 34246392
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now