• C

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?
gprconsultantsAsked:
Who is Participating?
 
Infinity08Commented:
Have a look at libjpeg :

        http://www.ijg.org/
0
 
ZoppoCommented:
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
 
gprconsultantsAuthor Commented:
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
Prepare for an Exciting Career in Cybersecurity

Help prevent cyber-threats and provide solutions to safeguard our global digital economy. Earn your MS in Cybersecurity. WGU’s MSCSIA degree program curriculum features two internationally recognized certifications from the EC-Council at no additional time or cost.

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

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

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

So, what was the problem with the colours ?
0
 
gprconsultantsAuthor Commented:
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
 
Infinity08Commented:
Ah. Nice find :)
0
 
evilrixSenior Software Engineer (Avast)Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.