Link to home
Start Free TrialLog in
Avatar of gprconsultants
gprconsultants

asked on

Jpeg header in c

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?
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gprconsultants
gprconsultants

ASKER

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
>> 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
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

I am working on 64x64 bmp image with depth=24 bits.
Could you post the original image, as well as the converted image you get ?
Hello ,
Original image. Also I have not posted the header files. Do i send it?
Anything you have that you think might be useful :)
sorry.
It has not added
lena2.bmp
NEW-IMAG.JPG
header files. Can I get the solution?
JGLOBALS.H
JTABLES.H
JTYPES.H
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.
can i comment out the code so that it becomes readable.
>> 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.
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.
>> 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.
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.

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++)
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.
After some modiications I got the image attched herewith

NEW-IMAG.JPG
Again thank you for your kind and prompt help. I am trying to solve the problem.
Hello Infinity08,
I got the solution. I have atteched the image here. Thanks.

NEW-IMAG.JPG
Great. Sorry I couldn't get back earlier. I haven't had the chance.

So, what was the problem with the colours ?
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.
Ah. Nice find :)
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.