Jump to content
  • Advertisement
Sign in to follow this  
Koobazaur

Problem with JPEG using IJG

This topic is 4210 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I am using the Independant JPEG Group developer sources to save and load a JPEG file. I have originally created my program for Dev-C++ on which it worked great but now, switching to MS Visual c++ 2003 I keep getting unhandled exceptions with my old .dll.a file. Well, I tried using a Win32 port fromhere which generates a static library file, but when I add that file to my project I get a whole bunch of linker errors:
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_write_scanlines referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_read_header referenced in function "struct HBITMAP__ * __cdecl LoadJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?LoadJPEG@@YAPAUHBITMAP__@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_read_scanlines referenced in function "struct HBITMAP__ * __cdecl LoadJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?LoadJPEG@@YAPAUHBITMAP__@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_set_defaults referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_set_quality referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_start_compress referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_start_decompress referenced in function "struct HBITMAP__ * __cdecl LoadJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?LoadJPEG@@YAPAUHBITMAP__@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_std_error referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_stdio_dest referenced in function "bool __cdecl SaveJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct HBITMAP__ *,int)" (?SaveJPEG@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHBITMAP__@@H@Z)
SignatureGenerator error LNK2019: unresolved external symbol _jpeg_stdio_src referenced in function "struct HBITMAP__ * __cdecl LoadJPEG(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?LoadJPEG@@YAPAUHBITMAP__@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)


FYI My full code looks like this: Header:
/*
    JPEG Save / Load

 This file provides functions for saving and loading a JPEG file.
 This is based on the IJG dlls for JPEG manipulation.
 
 Headers Required: jpeglib.h,  jconfig.h, jmorecfg.h, jerror.h,

*/
#ifndef JPEGSAVELOAD_H_
#define JPEGSAVELOAD_H_

#include <windows.h>
#include <string> 

#include "jpeglib.h"
#include "kBitmaps.h"

using namespace std;

//=============== SaveJPEG ========================
// Saves a 24 bit DIB bitmap to a JPEG file
// string szFilename - filename under which we want to 
//                     save the file
// HBITMAP bmp       - bitmap we want to save
// int quality       - quality of the jpeg (0-100)
// RETURN: 1 if succeded, 0 if failed
//==================================================  
bool SaveJPEG(string szFilename, HBITMAP bmp, int quality);


//=============== LoadJPEG ========================
// Loads a JPEG and returns it as a DIB bitmap
// string szFilename - filename of the image
// RETURN: returns the loaded DIB HBITMAP. 0 if failed
//==================================================  
HBITMAP LoadJPEG(string szFilename);
#endif



Cpp:
#include "jpegloadsave.h"


using namespace std;

//=============== SaveJPEG =====================================================
// Saves a 24 bit DIB bitmap to a JPEG file
// string szFilename - filename under which we want to save the file
// HBITMAP bmp       - bitmap we want to save
// int quality       - quality of the jpeg (0-100)
// RETURN: 1 if succeded, 0 if failed
//==============================================================================  
bool SaveJPEG(string szFilename, HBITMAP hbmp, int quality)
{     
 kBMPWrapper wBmp;       //wrapper for our bitmap
 JSAMPLE * image_buffer; //the image buffer that holds our image
 JSAMPLE * scanline;     //a buffer that will hold just single scanline. 
                         //Remember that in a BMP the colors are stored as BGR
                         //thus we must modify the order to get RGB this is 
                         //why we re-do each scanline separately  
   
 struct jpeg_compress_struct cinfo; //jpeg compression structure
 struct jpeg_error_mgr jerr;        //jpeg error structure
 FILE * outfile;                    //the file we are saving to (we use FILE 
                                    //instead of fstream as that what the
                                    //the JPEG library expects)

 //wrap wrapper around the bitmap
 wBmp.Wrap(hbmp);              
 //set the image buffer to the bitmap's data
 image_buffer = (JSAMPLE *)wBmp.GetPixelPointer();


  //STEP 1

  //Create the JPEG structures
  jpeg_create_compress(&cinfo);
  cinfo.err = jpeg_std_error(&jerr);
 
  //step 2

  //open the file for writing, make sure it works
  if( (outfile = fopen(szFilename.c_str(), "wb" )) == 0 ) 
	  return 0; 

  //set the file as the destination
  jpeg_stdio_dest(&cinfo, outfile);
  
  
  //Step 3: set parameters for compression

  cinfo.image_width = wBmp.GetWidth();      //width
  cinfo.image_height = wBmp.GetHeight();    //height
  cinfo.input_components = 3;               //bytes per pixel (24 bit)
  cinfo.in_color_space = JCS_RGB;           //RGB coloring 

  jpeg_set_defaults(&cinfo);                //defaults
  jpeg_set_quality(&cinfo, quality, TRUE);  //quality

  // Step 4: Start compressor 
  jpeg_start_compress(&cinfo, 1);
  
  //for each scanline; we are going from top to bottom because the
  //bitmap data is stored upside down relative to the JPEG
  for(int y=cinfo.image_height-1; y >= 0; y--)
  {
   //create a new scanline of the proper width (24bit)     
   scanline = new JSAMPLE[cinfo.image_width*3];  
   
   //now, for each pixel (NOT BYTE) in the scanline
   for(int x=0; x<cinfo.image_width; x++)
           {
            //fill the scanline with pixels from the current scanline
            scanline[x*3] = GetRValue(wBmp.GetPixel(x,y));
            scanline[x*3+1] = GetGValue(wBmp.GetPixel(x,y));
            scanline[x*3+2] = GetBValue(wBmp.GetPixel(x,y));    
           }    

   //pass it in
   jpeg_write_scanlines(&cinfo, &scanline, 1);
   
   //delete scanline 
   delete scanline;
  }
  
  //Step 6: Finish compression 
  
  jpeg_finish_compress(&cinfo); //finish 
  fclose(outfile);              //close file
  jpeg_destroy_compress(&cinfo);//destroy JPEG compression object

  //And we're done!  
  return 1; 
}

//=============== LoadJPEG ====================================================
// Loads a JPEG and returns it as a DIB bitmap
// string szFilename - filename of the image
// RETURN: returns the loaded DIB HBITMAP. 0 if failed
//==============================================================================  
HBITMAP LoadJPEG(string szFilename)
{
  	struct jpeg_decompress_struct cinfo; //JPEG decompression structure
	struct jpeg_error_mgr jerr;          //JPEG error structure    
	FILE * infile;                       //file we will read from (we use FILE 
                                         //instead of fstream as that what the
                                         //the JPEG library expects)
	HBITMAP Bitmap=NULL;                 //our bitmap we will load to
	kBMPWrapper wBmp;                    //bitmap wrapper
    JSAMPLE * image_buffer=0; 	         //the image buffer to which we'll write
    JSAMPLE * scanline=0;                //this will hold a single scanline

	
    //open file
	if ((infile = fopen(szFilename.c_str(), "rb")) == NULL)    
	    return NULL;
        	
    //Create the JPEG structures
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo); 	

	//set the source to our file
	jpeg_stdio_src(&cinfo, infile);
	
	//load the header
	jpeg_read_header(&cinfo, TRUE);

	//start decompression
	jpeg_start_decompress(&cinfo);
	
	//create the DIB bitmap, my good sir!
	Bitmap = CreateDIBBitmap(cinfo.output_width, cinfo.output_height);
	
	//wrap the wrapper so that we can write data
	wBmp.Wrap(Bitmap);
	
    //set the image buffer to the bitmap's data
	image_buffer = (JSAMPLE *)wBmp.GetPixelPointer();
	
//Remember that in a BMP the colors are stored as BGR
//thus we must modify the order to get RGB this is 
//why we re-do each scanline separately. Also, we are going 
//from top to bottom because the bitmap data is stored 
//upside down relative to the JPEG
  for(int y = cinfo.output_height-1; y >=0; y--)
        {  
         //create a scanline   
         scanline = new JSAMPLE[cinfo.output_width * cinfo.output_components];     
         
         //read it                        
         jpeg_read_scanlines(&cinfo, &scanline ,1);
         
         //for every pixel in the scanline
         for(int x=0; x<cinfo.output_width; x++)
           {
            //fill the scanline with pixels from the current scanline, switching order around    
            wBmp.SetPixel(x, y, RGB(scanline[x*3], scanline[x*3+1], scanline[x*3+2]));
           }  
             
          //delete scanline 
          delete scanline;
         }
            
 
	//end decompression
	jpeg_finish_decompress(&cinfo);
	
	//destroy the object because it's evil
	jpeg_destroy_decompress(&cinfo);
	
	//return the prepared ready bitmap	
	return Bitmap;
}


[Edited by - Koobazaur on April 6, 2007 3:16:39 AM]

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!