-
Notifications
You must be signed in to change notification settings - Fork 0
/
InitJPG.c
184 lines (144 loc) · 6.53 KB
/
InitJPG.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//***********************************************************************//
// $Description: Texture maps a QUAD with a JPG image //
// $Date: 4/23/02 //
//***********************************************************************//
#include "InitJPG.h"
////////////////////////////// DECODE JPG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This decodes the jpeg and fills in the tImageJPG structure
/////
////////////////////////////// DECODE JPG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void DecodeJPG(struct jpeg_decompress_struct* cinfo, tImageJPG *pImageData)
{
int i;
unsigned char** rowPtr;
int rowsRead = 0;
// Read in the header of the jpeg file
jpeg_read_header(cinfo, TRUE);
// Start to decompress the jpeg file with our compression info
jpeg_start_decompress(cinfo);
// Get the image dimensions and row span to read in the pixel data
pImageData->rowSpan = cinfo->image_width * cinfo->num_components;
pImageData->sizeX = cinfo->image_width;
pImageData->sizeY = cinfo->image_height;
// Allocate memory for the pixel buffer
// pImageData->data = new unsigned char[pImageData->rowSpan * pImageData->sizeY];
pImageData->data = (unsigned char *)malloc(pImageData->rowSpan * pImageData->sizeY);
// Here we use the library's state variable cinfo.output_scanline as the
// loop counter, so that we don't have to keep track ourselves.
// Create an array of row pointers
// unsigned char** rowPtr = new unsigned char*[pImageData->sizeY];
rowPtr = (unsigned char**)malloc(pImageData->sizeY * sizeof(unsigned char *));
for (i = 0; i < pImageData->sizeY; i++)
rowPtr[i] = &(pImageData->data[i*pImageData->rowSpan]);
// Now comes the juice of our work, here we extract all the pixel data
while (cinfo->output_scanline < cinfo->output_height)
{
// Read in the current row of pixels and increase the rowsRead count
rowsRead += jpeg_read_scanlines(cinfo, &rowPtr[rowsRead], cinfo->output_height - rowsRead);
}
// Delete the temporary row pointers
// delete [] rowPtr;
// Finish decompressing the data
jpeg_finish_decompress(cinfo);
}
///////////////////////////////// LOAD JPG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This loads the JPG file and returns it's data in a tImageJPG struct
/////
///////////////////////////////// LOAD JPG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
tImageJPG *LoadJPG(const char *filename)
{
struct jpeg_decompress_struct cinfo;
tImageJPG *pImageData = NULL;
FILE *pFile;
// Create an error handler
struct jpeg_error_mgr jerr;
// This is the only function you should care about. You don't need to
// really know what all of this does (since you can't cause it's a library!) :)
// Just know that you need to pass in the jpeg file name, and get a pointer
// to a tImageJPG structure which contains the width, height and pixel data.
// Be sure to free the data after you are done with it, just like a bitmap.
// Open a file pointer to the jpeg file and check if it was found and opened
if((pFile = fopen(filename, "rb")) == NULL)
{
// Display an error message saying the file was not found, then return NULL
fprintf(stderr, "Unable to load JPG File %s!", filename );
return NULL;
}
// Have our compression info object point to the error handler address
cinfo.err = jpeg_std_error(&jerr);
// Initialize the decompression object
jpeg_create_decompress(&cinfo);
// Specify the data source (Our file pointer)
jpeg_stdio_src(&cinfo, pFile);
// Allocate the structure that will hold our eventual jpeg data (must free it!)
pImageData = (tImageJPG*)malloc(sizeof(tImageJPG));
// Decode the jpeg file and fill in the image data structure to pass back
DecodeJPG(&cinfo, pImageData);
// This releases all the stored memory for reading and decoding the jpeg
jpeg_destroy_decompress(&cinfo);
// Close the file pointer that opened the file
fclose(pFile);
// Return the jpeg data (remember, you must free this data after you are done)
return pImageData;
}
///////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This creates a texture in OpenGL that we can use as a texture map
/////
///////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CreateTexture(GLuint textureArray[], char * strFileName, int textureID)
{
tImageJPG *pImage;
if(!strFileName) // Return from the function if no filename was passed in
return;
pImage = LoadJPG(strFileName); // Load the image and store the data
if(pImage == NULL) // If we can't load the file, quit!
exit(0);
// Generate a texture with the associative texture ID stored in the array
glGenTextures(1, &textureArray[textureID]);
// Bind the texture to the texture arrays index and init the texture
glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);
// Build Mipmaps (builds different versions of the picture for distances - looks better)
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
// Lastly, we need to tell OpenGL the quality of our texture map. GL_LINEAR_MIPMAP_LINEAR
// is the smoothest. GL_LINEAR_MIPMAP_NEAREST is faster than GL_LINEAR_MIPMAP_LINEAR,
// but looks blochy and pixilated. Good for slower computers though.
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
// Now we need to free the image data that we loaded since OpenGL stored it as a texture
if (pImage) // If we loaded the image
{
if (pImage->data) // If there is texture data
{
free(pImage->data); // Free the texture data, we don't need it anymore
}
free(pImage); // Free the image structure
}
}
//////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES *
//
// BE SURE TO INCLUDE jpeg.lib and jpeglib.h IN YOUR PROJECTS TO USE CreateTexture().
//
// In this version of our texture mapping tutorials, we added a jpeg loader. The
// library was developed by Thomas G. Lane - Independent JPEG Group's software.
//
// Here is the info for the jpeg library:
//
// * Copyright (C) 1991-1998, Thomas G. Lane.
// * The jpeglib.h and jpeg.lib files are part of the Independent JPEG Group's software.
// * For conditions of distribution and use, visit the website at: http://www.ijg.org/
//
// Note, that I added my own structure for the jpeg info, tImageJPG. This is not
// part of the library. I also combined the jconfig.h and jmoreconfig.h into jpeglib.h
//
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
//
//