1 ////////////////////////////////////////////////////////////////////////////
2 //	File:		GLTexImage.cpp
3 //	Author:		Changchang Wu
4 //	Description : implementation of the GLTexImage class.
5 //
6 //
7 //
8 //	Copyright (c) 2007 University of North Carolina at Chapel Hill
9 //	All Rights Reserved
10 //
11 //	Permission to use, copy, modify and distribute this software and its
12 //	documentation for educational, research and non-profit purposes, without
13 //	fee, and without a written agreement is hereby granted, provided that the
14 //	above copyright notice and the following paragraph appear in all copies.
15 //
16 //	The University of North Carolina at Chapel Hill make no representations
17 //	about the suitability of this software for any purpose. It is provided
18 //	'as is' without express or implied warranty.
19 //
20 //	Please send BUG REPORTS to ccwu@cs.unc.edu
21 //
22 ////////////////////////////////////////////////////////////////////////////
23 
24 
25 #include "GL/glew.h"
26 #include <stdio.h>
27 #include <iostream>
28 #include <fstream>
29 #include <vector>
30 #include <algorithm>
31 #include <stdlib.h>
32 #include <math.h>
33 using namespace std;
34 
35 
36 
37 #include "GlobalUtil.h"
38 
39 #include "GLTexImage.h"
40 #include "FrameBufferObject.h"
41 #include "ShaderMan.h"
42 
43 
44 //#define SIFTGPU_NO_DEVIL
45 
46 #ifndef SIFTGPU_NO_DEVIL
47     #include "IL/il.h"
48 #else
49 	#include <string.h>
50 #endif
51 //////////////////////////////////////////////////////////////////////
52 // Construction/Destruction
53 //////////////////////////////////////////////////////////////////////
54 
55 
GLTexImage()56 GLTexImage::GLTexImage()
57 {
58 	_imgWidth = _imgHeight = 0;
59 	_texWidth = _texHeight = 0;
60 	_drawWidth = _drawHeight = 0;
61 	_texID = 0;
62 
63 }
64 
~GLTexImage()65 GLTexImage::~GLTexImage()
66 {
67 	if(_texID) glDeleteTextures(1, &_texID);
68 }
69 
CheckTexture()70 int GLTexImage::CheckTexture()
71 {
72 	if(_texID)
73 	{
74 		GLint tw, th;
75 		BindTex();
76 		glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_WIDTH , &tw);
77 		glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_HEIGHT , &th);
78 		UnbindTex();
79 		return tw == _texWidth && th == _texHeight;
80 	}else
81 	{
82 		return _texWidth == 0 && _texHeight ==0;
83 
84 	}
85 }
86 //set a dimension that is smaller than the actuall size
87 //for drawQuad
SetImageSize(int width,int height)88 void GLTexImage::SetImageSize( int width,  int height)
89 {
90 	_drawWidth  = _imgWidth =  width;
91 	_drawHeight = _imgHeight =  height;
92 }
93 
InitTexture(int width,int height,int clamp_to_edge)94 void GLTexImage::InitTexture( int width,  int height, int clamp_to_edge)
95 {
96 
97 	if(_texID && width == _texWidth && height == _texHeight ) return;
98 	if(_texID==0)	glGenTextures(1, &_texID);
99 
100 	_texWidth = _imgWidth = _drawWidth = width;
101 	_texHeight = _imgHeight = _drawHeight = height;
102 
103 	BindTex();
104 
105 	if(clamp_to_edge)
106 	{
107 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
108 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
109 	}else
110 	{
111 		//out of bound tex read returns 0??
112 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
113 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
114 	}
115 	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
116 	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
117 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
118 
119 	glTexImage2D(_texTarget, 0, _iTexFormat,
120 		_texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
121 	CheckErrorsGL("glTexImage2D");
122 
123 
124 	UnbindTex();
125 
126 }
127 
128 
InitTexture(int width,int height,int clamp_to_edge,GLuint format)129 void GLTexImage::InitTexture( int width,  int height, int clamp_to_edge, GLuint format)
130 {
131 
132 	if(_texID && width == _texWidth && height == _texHeight ) return;
133 	if(_texID==0)	glGenTextures(1, &_texID);
134 
135 	_texWidth = _imgWidth = _drawWidth = width;
136 	_texHeight = _imgHeight = _drawHeight = height;
137 
138 	BindTex();
139 
140 	if(clamp_to_edge)
141 	{
142 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
143 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
144 	}else
145 	{
146 		//out of bound tex read returns 0??
147 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
148 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
149 	}
150 	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
151 	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
152 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
153 
154 	glTexImage2D(_texTarget, 0, format, _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
155 
156 	UnbindTex();
157 
158 }
BindTex()159 void  GLTexImage::BindTex()
160 {
161 	glBindTexture(_texTarget, _texID);
162 }
163 
UnbindTex()164 void  GLTexImage::UnbindTex()
165 {
166 	glBindTexture(_texTarget, 0);
167 }
168 
169 
DrawQuad()170 void  GLTexImage::DrawQuad()
171 {
172 	glBegin (GL_QUADS);
173 		glTexCoord2i ( 0			,   0   ); 				glVertex2i   ( 0			,		0   );
174 		glTexCoord2i ( 0			,   _drawHeight  );		glVertex2i   ( 0			,		_drawHeight   );
175  		glTexCoord2i ( _drawWidth   ,   _drawHeight  ); 	glVertex2i   ( _drawWidth	,		_drawHeight   );
176 		glTexCoord2i ( _drawWidth	,   0   ); 				glVertex2i   ( _drawWidth	,		0   );
177 	glEnd ();
178 	glFlush();
179 }
180 
FillMargin(int marginx,int marginy)181 void GLTexImage::FillMargin(int marginx, int marginy)
182 {
183 	//
184 	marginx = min(marginx, _texWidth - _imgWidth);
185 	marginy = min(marginy, _texHeight - _imgHeight);
186 	if(marginx >0 || marginy > 0)
187 	{
188 		GlobalUtil::FitViewPort(_imgWidth + marginx, _imgHeight + marginy);
189 		AttachToFBO(0);
190 		BindTex();
191 		ShaderMan::UseShaderMarginCopy(_imgWidth, _imgHeight);
192 		DrawMargin(_imgWidth + marginx, _imgHeight + marginy);
193 	}
194 }
195 
ZeroHistoMargin()196 void GLTexImage::ZeroHistoMargin()
197 {
198 	ZeroHistoMargin(_imgWidth, _imgHeight);
199 }
200 
ZeroHistoMargin(int width,int height)201 void GLTexImage::ZeroHistoMargin(int width, int height)
202 {
203 	int marginx = width & 0x01;
204 	int marginy = height & 0x01;
205 	if(marginx >0 || marginy > 0)
206 	{
207 		int right = width + marginx;
208 		int bottom = height + marginy;
209 		GlobalUtil::FitViewPort(right, bottom);
210 		AttachToFBO(0);
211 		ShaderMan::UseShaderZeroPass();
212 		glBegin(GL_QUADS);
213 		if(right > width && _texWidth > width)
214 		{
215 			glTexCoord2i ( width	,   0   ); 				glVertex2i   ( width	,		0   );
216 			glTexCoord2i ( width	,   bottom  );			glVertex2i   ( width	,		bottom   );
217 			glTexCoord2i ( right	,   bottom  ); 			glVertex2i   ( right	,		bottom   );
218 			glTexCoord2i ( right	,   0   ); 				glVertex2i   ( right	,		0   );
219 		}
220 		if(bottom>height && _texHeight > height)
221 		{
222 			glTexCoord2i ( 0		,   height ); 		glVertex2i   ( 0		,		height   );
223 			glTexCoord2i ( 0		,   bottom	);		glVertex2i   ( 0		,		bottom		 );
224 			glTexCoord2i ( width	,   bottom	); 		glVertex2i   ( width	,		bottom		 );
225 			glTexCoord2i ( width	,   height	); 		glVertex2i   ( width	,		height	 );
226 		}
227 		glEnd();
228 		glFlush();
229 	}
230 
231 }
232 
DrawMargin(int right,int bottom)233 void GLTexImage::DrawMargin(int right, int bottom)
234 {
235 	glBegin(GL_QUADS);
236 	if(right > _drawWidth)
237 	{
238 		glTexCoord2i ( _drawWidth	,   0   ); 				glVertex2i   ( _drawWidth	,		0   );
239 		glTexCoord2i ( _drawWidth	,   bottom  );			glVertex2i   ( _drawWidth	,		bottom   );
240 		glTexCoord2i ( right		,   bottom  ); 			glVertex2i   ( right		,		bottom   );
241 		glTexCoord2i ( right		,   0   ); 				glVertex2i   ( right		,		0   );
242 	}
243 	if(bottom>_drawHeight)
244 	{
245 		glTexCoord2i ( 0			,   _drawHeight ); 		glVertex2i   ( 0			,		_drawHeight   );
246 		glTexCoord2i ( 0			,   bottom		);		glVertex2i   ( 0			,		bottom		 );
247 		glTexCoord2i ( _drawWidth	,   bottom		); 		glVertex2i   ( _drawWidth	,		bottom		 );
248 		glTexCoord2i ( _drawWidth	,   _drawHeight	); 		glVertex2i   ( _drawWidth	,		_drawHeight	 );
249 	}
250 	glEnd();
251 	glFlush();
252 
253 
254 }
255 
256 
DrawQuadMT4()257 void GLTexImage::DrawQuadMT4()
258 {
259 	int w = _drawWidth, h = _drawHeight;
260 	glBegin (GL_QUADS);
261 		glMultiTexCoord2i( GL_TEXTURE0, 0		,   0  );
262 		glMultiTexCoord2i( GL_TEXTURE1, -1		,   0  );
263 		glMultiTexCoord2i( GL_TEXTURE2, 1		,   0  );
264 		glMultiTexCoord2i( GL_TEXTURE3, 0		,   -1  );
265 		glMultiTexCoord2i( GL_TEXTURE4, 0		,   1  );
266 		glVertex2i   ( 0			,		0   );
267 
268 		glMultiTexCoord2i( GL_TEXTURE0, 0		,   h  );
269 		glMultiTexCoord2i( GL_TEXTURE1, -1		,   h  );
270 		glMultiTexCoord2i( GL_TEXTURE2, 1		,   h );
271 		glMultiTexCoord2i( GL_TEXTURE3, 0		,   h -1 );
272 		glMultiTexCoord2i( GL_TEXTURE4, 0		,   h +1 );
273 		glVertex2i   ( 0			,		h   );
274 
275 
276 		glMultiTexCoord2i( GL_TEXTURE0, w		,   h  );
277 		glMultiTexCoord2i( GL_TEXTURE1, w-1		,   h  );
278 		glMultiTexCoord2i( GL_TEXTURE2, w+1		,   h  );
279 		glMultiTexCoord2i( GL_TEXTURE3, w		,   h-1  );
280 		glMultiTexCoord2i( GL_TEXTURE4, w		,   h+1  );
281 		glVertex2i   ( w	,		h   );
282 
283 		glMultiTexCoord2i( GL_TEXTURE0, w		,   0  );
284 		glMultiTexCoord2i( GL_TEXTURE1, w-1		,   0  );
285 		glMultiTexCoord2i( GL_TEXTURE2, w+1		,   0  );
286 		glMultiTexCoord2i( GL_TEXTURE3, w		,   -1  );
287 		glMultiTexCoord2i( GL_TEXTURE4, w		,   1  );
288 		glVertex2i   ( w	,		0   );
289 	glEnd ();
290 	glFlush();
291 }
292 
293 
DrawQuadMT8()294 void GLTexImage::DrawQuadMT8()
295 {
296 	int w = _drawWidth;
297 	int h = _drawHeight;
298 	glBegin (GL_QUADS);
299 		glMultiTexCoord2i( GL_TEXTURE0, 0		,   0  );
300 		glMultiTexCoord2i( GL_TEXTURE1, -1		,   0  );
301 		glMultiTexCoord2i( GL_TEXTURE2, 1		,   0  );
302 		glMultiTexCoord2i( GL_TEXTURE3, 0		,   -1  );
303 		glMultiTexCoord2i( GL_TEXTURE4, 0		,   1  );
304 		glMultiTexCoord2i( GL_TEXTURE5, -1		,   -1  );
305 		glMultiTexCoord2i( GL_TEXTURE6, -1		,   1  );
306 		glMultiTexCoord2i( GL_TEXTURE7, 1		,   -1  );
307 		glVertex2i   ( 0			,		0   );
308 
309 		glMultiTexCoord2i( GL_TEXTURE0, 0		,   h    );
310 		glMultiTexCoord2i( GL_TEXTURE1, -1		,   h    );
311 		glMultiTexCoord2i( GL_TEXTURE2, 1		,   h    );
312 		glMultiTexCoord2i( GL_TEXTURE3, 0		,   h  -1  );
313 		glMultiTexCoord2i( GL_TEXTURE4, 0		,   h  +1  );
314 		glMultiTexCoord2i( GL_TEXTURE5, -1		,   h  -1  );
315 		glMultiTexCoord2i( GL_TEXTURE6, -1		,   h  +1  );
316 		glMultiTexCoord2i( GL_TEXTURE7, 1		,   h  -1  );
317 		glVertex2i   ( 0			,		h   );
318 
319 
320 		glMultiTexCoord2i( GL_TEXTURE0, w		,   h    );
321 		glMultiTexCoord2i( GL_TEXTURE1, w-1		,   h    );
322 		glMultiTexCoord2i( GL_TEXTURE2, w+1		,   h    );
323 		glMultiTexCoord2i( GL_TEXTURE3, w		,   h  -1  );
324 		glMultiTexCoord2i( GL_TEXTURE4, w		,   h  +1  );
325 		glMultiTexCoord2i( GL_TEXTURE5, w-1		,   h  -1  );
326 		glMultiTexCoord2i( GL_TEXTURE6, w-1		,   h  +1  );
327 		glMultiTexCoord2i( GL_TEXTURE7, w+1		,   h  -1  );
328 		glVertex2i   ( w	,		h   );
329 
330 		glMultiTexCoord2i( GL_TEXTURE0, w		,   0  );
331 		glMultiTexCoord2i( GL_TEXTURE1, w-1		,   0  );
332 		glMultiTexCoord2i( GL_TEXTURE2, w+1		,   0  );
333 		glMultiTexCoord2i( GL_TEXTURE3, w		,   -1  );
334 		glMultiTexCoord2i( GL_TEXTURE4, w		,   1  );
335 		glMultiTexCoord2i( GL_TEXTURE5, w-1		,   -1  );
336 		glMultiTexCoord2i( GL_TEXTURE6, w-1		,   1  );
337 		glMultiTexCoord2i( GL_TEXTURE7, w+1		,   -1  );
338 		glVertex2i   ( w	,		0   );
339 	glEnd ();
340 	glFlush();
341 }
342 
343 
344 
345 
DrawImage()346 void GLTexImage::DrawImage()
347 {
348 	DrawQuad();
349 }
350 
351 
352 
FitTexViewPort()353 void GLTexImage::FitTexViewPort()
354 {
355 	GlobalUtil::FitViewPort(_drawWidth, _drawHeight);
356 }
357 
FitRealTexViewPort()358 void GLTexImage::FitRealTexViewPort()
359 {
360 	GlobalUtil::FitViewPort(_texWidth, _texHeight);
361 }
362 
AttachToFBO(int i)363 void  GLTexImage::AttachToFBO(int i)
364 {
365 	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, _texID, 0 );
366 }
367 
DetachFBO(int i)368 void  GLTexImage::DetachFBO(int i)
369 {
370 	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, 0, 0 );
371 }
372 
373 
DrawQuad(float x1,float x2,float y1,float y2)374 void GLTexImage::DrawQuad(float x1, float x2, float y1, float y2)
375 {
376 
377 	glBegin (GL_QUADS);
378 		glTexCoord2f ( x1	,   y1   ); 	glVertex2f   ( x1	,		y1   );
379 		glTexCoord2f ( x1	,   y2  );		glVertex2f   ( x1	,		y2   );
380  		glTexCoord2f ( x2   ,   y2  ); 		glVertex2f   ( x2	,		y2   );
381 		glTexCoord2f ( x2	,   y1   ); 	glVertex2f   ( x2	,		y1   );
382 	glEnd ();
383 	glFlush();
384 }
385 
TexConvertRGB()386 void GLTexImage::TexConvertRGB()
387 {
388 	//change 3/22/09
389 	FrameBufferObject fbo;
390 	//GlobalUtil::FitViewPort(1, 1);
391 	FitTexViewPort();
392 
393 	AttachToFBO(0);
394 	ShaderMan::UseShaderRGB2Gray();
395 	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
396 	DrawQuad();
397 	ShaderMan::UnloadProgram();
398 	DetachFBO(0);
399 }
400 
DrawQuadDS(int scale)401 void GLTexImage::DrawQuadDS(int scale)
402 {
403 	DrawScaledQuad(float(scale));
404 }
405 
DrawQuadUS(int scale)406 void GLTexImage::DrawQuadUS(int scale)
407 {
408 	DrawScaledQuad(1.0f/scale);
409 }
410 
DrawScaledQuad(float texscale)411 void GLTexImage::DrawScaledQuad(float texscale)
412 {
413 
414 	////the texture coordinate for 0.5 is to + 0.5*texscale
415 	float to = 0.5f -0.5f * texscale;
416 	float tx =  _imgWidth*texscale +to;
417 	float ty = _imgHeight*texscale +to;
418 	glBegin (GL_QUADS);
419 		glTexCoord2f ( to	,   to   ); 	glVertex2i   ( 0			,		0   );
420 		glTexCoord2f ( to	,   ty  );		glVertex2i   ( 0			,		_imgHeight   );
421  		glTexCoord2f ( tx	,	ty ); 		glVertex2i   ( _imgWidth	,		_imgHeight   );
422 		glTexCoord2f ( tx	,   to   ); 	glVertex2i   ( _imgWidth	,		0   );
423 	glEnd ();
424 	glFlush();
425 }
426 
427 
DrawQuadReduction(int w,int h)428 void GLTexImage::DrawQuadReduction(int w , int h)
429 {
430 	float to = -0.5f;
431 	float tx = w*2 +to;
432 	float ty = h*2 +to;
433 	glBegin (GL_QUADS);
434 		glMultiTexCoord2f ( GL_TEXTURE0, to	,	to   );
435 		glMultiTexCoord2f ( GL_TEXTURE1, to	+1,	to   );
436 		glMultiTexCoord2f ( GL_TEXTURE2, to	,	to+1  );
437 		glMultiTexCoord2f ( GL_TEXTURE3, to	+1,	to+1  );
438 		glVertex2i   ( 0			,		0   );
439 
440 		glMultiTexCoord2f ( GL_TEXTURE0, to	,   ty  );
441 		glMultiTexCoord2f ( GL_TEXTURE1, to	+1, ty  );
442 		glMultiTexCoord2f ( GL_TEXTURE2, to	,   ty +1 );
443 		glMultiTexCoord2f ( GL_TEXTURE3, to	+1, ty +1 );
444 		glVertex2i   ( 0			,		h   );
445 
446  		glMultiTexCoord2f ( GL_TEXTURE0, tx	,	ty );
447  		glMultiTexCoord2f ( GL_TEXTURE1, tx	+1,	ty );
448  		glMultiTexCoord2f ( GL_TEXTURE2, tx	,	ty +1);
449  		glMultiTexCoord2f ( GL_TEXTURE3, tx	+1,	ty +1);
450 
451 		glVertex2i   ( w	,		h   );
452 
453 		glMultiTexCoord2f ( GL_TEXTURE0, tx	,   to   );
454 		glMultiTexCoord2f ( GL_TEXTURE1, tx	+1, to   );
455 		glMultiTexCoord2f ( GL_TEXTURE2, tx	,   to +1  );
456 		glMultiTexCoord2f ( GL_TEXTURE3, tx	+1, to +1  );
457 		glVertex2i   ( w	,		0   );
458 	glEnd ();
459 
460 	glFlush();
461 }
462 
463 
DrawQuadReduction()464 void GLTexImage::DrawQuadReduction()
465 {
466 	float to = -0.5f;
467 	float tx = _drawWidth*2 +to;
468 	float ty = _drawHeight*2 +to;
469 	glBegin (GL_QUADS);
470 		glMultiTexCoord2f ( GL_TEXTURE0, to	,	to   );
471 		glMultiTexCoord2f ( GL_TEXTURE1, to	+1,	to   );
472 		glMultiTexCoord2f ( GL_TEXTURE2, to	,	to+1  );
473 		glMultiTexCoord2f ( GL_TEXTURE3, to	+1,	to+1  );
474 		glVertex2i   ( 0			,		0   );
475 
476 		glMultiTexCoord2f ( GL_TEXTURE0, to	,   ty  );
477 		glMultiTexCoord2f ( GL_TEXTURE1, to	+1, ty  );
478 		glMultiTexCoord2f ( GL_TEXTURE2, to	,   ty +1 );
479 		glMultiTexCoord2f ( GL_TEXTURE3, to	+1, ty +1 );
480 		glVertex2i   ( 0			,		_drawHeight   );
481 
482  		glMultiTexCoord2f ( GL_TEXTURE0, tx	,	ty );
483  		glMultiTexCoord2f ( GL_TEXTURE1, tx	+1,	ty );
484  		glMultiTexCoord2f ( GL_TEXTURE2, tx	,	ty +1);
485  		glMultiTexCoord2f ( GL_TEXTURE3, tx	+1,	ty +1);
486 
487 		glVertex2i   ( _drawWidth	,		_drawHeight   );
488 
489 		glMultiTexCoord2f ( GL_TEXTURE0, tx	,   to   );
490 		glMultiTexCoord2f ( GL_TEXTURE1, tx	+1, to   );
491 		glMultiTexCoord2f ( GL_TEXTURE2, tx	,   to +1  );
492 		glMultiTexCoord2f ( GL_TEXTURE3, tx	+1, to +1  );
493 		glVertex2i   ( _drawWidth	,		0   );
494 	glEnd ();
495 
496 	glFlush();
497 }
498 
TexConvertRGB()499 void GLTexPacked::TexConvertRGB()
500 {
501 	//update the actual size of daw area
502 	_drawWidth  = (1 + _imgWidth) >> 1;
503 	_drawHeight = (1 + _imgHeight) >> 1;
504 	///
505 	FrameBufferObject fbo;
506 	GLuint oldTexID = _texID;
507 	glGenTextures(1, &_texID);
508 	glBindTexture(_texTarget, _texID);
509 	glTexImage2D(_texTarget, 0, _iTexFormat, _texWidth,	_texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,	NULL);
510 
511 	//input
512 	glBindTexture(_texTarget, oldTexID);
513 	//output
514 	AttachToFBO(0);
515 	//program
516 	ShaderMan::UseShaderRGB2Gray();
517 	//draw buffer
518 	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
519 	//run
520 	DrawQuadDS(2);
521 	ShaderMan::UnloadProgram();
522 
523 	glDeleteTextures(1, &oldTexID);
524 	DetachFBO(0);
525 }
526 
527 
SetImageSize(int width,int height)528 void GLTexPacked::SetImageSize( int width,  int height)
529 {
530 	_imgWidth =  width;		_drawWidth = (width + 1) >> 1;
531 	_imgHeight =  height;	_drawHeight = (height + 1) >> 1;
532 }
533 
InitTexture(int width,int height,int clamp_to_edge)534 void GLTexPacked::InitTexture( int width,  int height, int clamp_to_edge)
535 {
536 
537 	if(_texID && width == _imgWidth && height == _imgHeight ) return;
538 	if(_texID==0)	glGenTextures(1, &_texID);
539 
540 	_imgWidth = width;
541 	_imgHeight = height;
542 	if(GlobalUtil::_PreciseBorder)
543 	{
544 		_texWidth = (width + 2) >> 1;
545 		_texHeight = (height + 2) >> 1;
546 	}else
547 	{
548 		_texWidth = (width + 1) >> 1;
549 		_texHeight = (height + 1) >> 1;
550 	}
551 	_drawWidth = (width + 1) >> 1;
552 	_drawHeight = (height + 1) >> 1;
553 
554 	BindTex();
555 
556 	if(clamp_to_edge)
557 	{
558 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
559 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
560 	}else
561 	{
562 		//out of bound tex read returns 0??
563 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
564 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
565 	}
566 	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
567 	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
568 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
569 
570 	glTexImage2D(_texTarget, 0, _iTexFormat,
571 		_texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
572 
573 	UnbindTex();
574 
575 }
576 
577 
DrawImage()578 void  GLTexPacked::DrawImage()
579 {
580 	float x1 =0,  y1 = 0; //border..
581 	float x2 = _imgWidth*0.5f +x1;
582 	float y2 = _imgHeight*0.5f + y1;
583 	glBegin (GL_QUADS);
584 		glTexCoord2f ( x1	,   y1  ); 			glVertex2i   ( 0			,		0   );
585 		glTexCoord2f ( x1	,   y2 );			glVertex2i   ( 0			,		_imgHeight   );
586  		glTexCoord2f ( x2   ,   y2  ); 			glVertex2i   ( _imgWidth	,		_imgHeight   );
587 		glTexCoord2f ( x2	,   y1   ); 		glVertex2i   ( _imgWidth	,		0   );
588 	glEnd ();
589 	glFlush();
590 }
591 
DrawQuadUS(int scale)592 void GLTexPacked::DrawQuadUS(int scale)
593 {
594 	int tw =_drawWidth, th = _drawHeight;
595 	float texscale = 1.0f / scale;
596 	float x1 = 0.5f - 0.5f*scale, y1 = x1;
597 	float x2 = tw * texscale + x1;
598 	float y2 = th * texscale + y1;
599 	float step = texscale *0.5f;
600 	glBegin (GL_QUADS);
601 		glMultiTexCoord2f( GL_TEXTURE0, x1		,   y1      );
602 		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y1      );
603 		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y1 +step);
604 		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y1 +step);
605 		glVertex2i   ( 0			,		0   );
606 
607 		glMultiTexCoord2f( GL_TEXTURE0, x1		,	y2      );
608 		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y2      );
609 		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y2 +step);
610 		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y2 +step);
611 		glVertex2i   ( 0			,	th   );
612 
613 		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y2      );
614 		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y2      );
615 		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y2 +step);
616 		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y2 +step);
617 		glVertex2i   ( tw	,	th   );
618 
619 		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y1      );
620 		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y1      );
621 		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y1 +step);
622 		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y1 +step);
623 		glVertex2i   ( tw	,	0   );
624 	glEnd ();
625 }
626 
DrawQuadDS(int scale)627 void GLTexPacked::DrawQuadDS(int scale)
628 {
629 	int tw = _drawWidth;
630 	int th = _drawHeight;
631 	float x1 = 0.5f - 0.5f*scale;
632 	float x2 = tw * scale + x1;
633 	float y1 = 0.5f - 0.5f * scale;
634 	float y2 = th * scale + y1;
635 	int step = scale / 2;
636 
637 	glBegin (GL_QUADS);
638 		glMultiTexCoord2f( GL_TEXTURE0, x1		,   y1      );
639 		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y1      );
640 		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y1 +step);
641 		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y1 +step);
642 		glVertex2i   ( 0			,		0   );
643 
644 		glMultiTexCoord2f( GL_TEXTURE0, x1		,	y2      );
645 		glMultiTexCoord2f( GL_TEXTURE1, x1+step	,   y2      );
646 		glMultiTexCoord2f( GL_TEXTURE2, x1   	,   y2 +step);
647 		glMultiTexCoord2f( GL_TEXTURE3, x1+step	,   y2 +step);
648 		glVertex2i   ( 0			,	th   );
649 
650 		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y2      );
651 		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y2      );
652 		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y2 +step);
653 		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y2 +step);
654 		glVertex2i   ( tw	,	th   );
655 
656 		glMultiTexCoord2f( GL_TEXTURE0, x2		,   y1      );
657 		glMultiTexCoord2f( GL_TEXTURE1, x2+step	,   y1      );
658 		glMultiTexCoord2f( GL_TEXTURE2, x2   	,   y1 +step);
659 		glMultiTexCoord2f( GL_TEXTURE3, x2+step	,   y1 +step);
660 		glVertex2i   ( tw	,	0   );
661 	glEnd ();
662 }
663 
ZeroHistoMargin()664 void GLTexPacked::ZeroHistoMargin()
665 {
666 	int marginx = (((_imgWidth  + 3) /4)*4) - _imgWidth;
667 	int marginy = (((-_imgHeight + 3)/4)*4) - _imgHeight;
668 	if(marginx >0 || marginy > 0)
669 	{
670 		int tw = (_imgWidth + marginx ) >> 1;
671 		int th = (_imgHeight + marginy ) >> 1;
672 		tw = min(_texWidth, tw );
673 		th = min(_texHeight, th);
674 		GlobalUtil::FitViewPort(tw, th);
675 		AttachToFBO(0);
676 		BindTex();
677 		ShaderMan::UseShaderZeroPass();
678 		DrawMargin(tw, th, 1, 1);
679 	}
680 }
681 
682 
FillMargin(int marginx,int marginy)683 void GLTexPacked::FillMargin(int marginx, int marginy)
684 {
685 	//
686 	marginx = min(marginx, _texWidth * 2 - _imgWidth);
687 	marginy = min(marginy, _texHeight * 2 - _imgHeight);
688 	if(marginx >0 || marginy > 0)
689 	{
690 		int tw = (_imgWidth + marginx + 1) >> 1;
691 		int th = (_imgHeight + marginy + 1) >> 1;
692 		GlobalUtil::FitViewPort(tw, th);
693 		BindTex();
694 		AttachToFBO(0);
695 		ShaderMan::UseShaderMarginCopy(_imgWidth , _imgHeight);
696 		DrawMargin(tw, th, marginx, marginy);
697 	}
698 }
DrawMargin(int right,int bottom,int mx,int my)699 void GLTexPacked::DrawMargin(int right, int bottom, int mx, int my)
700 {
701 	int tw = (_imgWidth >>1);
702 	int th = (_imgHeight >>1);
703 	glBegin(GL_QUADS);
704 	if(right>tw && mx)
705 	{
706 		glTexCoord2i ( tw	,   0   ); 				glVertex2i   ( tw	,		0   );
707 		glTexCoord2i ( tw	,   bottom  );			glVertex2i   ( tw	,		bottom   );
708 		glTexCoord2i ( right,   bottom  ); 			glVertex2i   ( right,		bottom   );
709 		glTexCoord2i ( right,   0   ); 				glVertex2i   ( right,		0   );
710 	}
711 	if(bottom>th && my)
712 	{
713 		glTexCoord2i ( 0	,   th  ); 		glVertex2i   ( 0	,		th   );
714 		glTexCoord2i ( 0	,   bottom	);	glVertex2i   ( 0	,		bottom	 );
715 		glTexCoord2i ( tw	,   bottom	); 	glVertex2i   ( tw	,		bottom	 );
716 		glTexCoord2i ( tw	,   th	); 		glVertex2i   ( tw	,		th	 );
717 	}
718 	glEnd();
719 	glFlush();
720 
721 }
722 
723 
UnbindMultiTex(int n)724 void GLTexImage::UnbindMultiTex(int n)
725 {
726 	for(int i = n-1; i>=0; i--)
727 	{
728 		glActiveTexture(GL_TEXTURE0+i);
729 		glBindTexture(_texTarget, 0);
730 	}
731 }
732 
733 template <class Uint> int
734 
735 #if !defined(_MSC_VER) || _MSC_VER > 1200
736 GLTexInput::
737 #endif
738 
DownSamplePixelDataI(unsigned int gl_format,int width,int height,int ds,const Uint * pin,Uint * pout)739 DownSamplePixelDataI(unsigned int gl_format, int width, int height, int ds,
740 									const Uint * pin, Uint * pout)
741 {
742 	int step, linestep;
743 	int i, j;
744 	int ws = width/ds;
745 	int hs = height/ds;
746 	const Uint * line = pin, * p;
747 	Uint *po = pout;
748 	switch(gl_format)
749 	{
750 	case GL_LUMINANCE:
751 	case GL_LUMINANCE_ALPHA:
752 		step = ds * (gl_format == GL_LUMINANCE? 1: 2);
753 		linestep = width * step;
754 		for(i = 0 ; i < hs; i++, line+=linestep)
755 		{
756 			for(j = 0, p = line; j < ws; j++, p+=step)
757 			{
758 				*po++ = *p;
759 			}
760 		}
761 		break;
762 	case GL_RGB:
763 	case GL_RGBA:
764 		step = ds * (gl_format == GL_RGB? 3: 4);
765 		linestep = width * step;
766 
767 		for(i = 0 ; i < hs; i++, line+=linestep)
768 		{
769 			for(j = 0, p = line; j < ws; j++, p+=step)
770 			{
771 				//*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5);
772 				*po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]+ 32768)>>16);
773 			}
774 		}
775 		break;
776 	case GL_BGR:
777 	case GL_BGRA:
778 		step = ds * (gl_format == GL_BGR? 3: 4);
779 		linestep = width * step;
780 		for(i = 0 ; i < hs; i++, line+=linestep)
781 		{
782 			for(j = 0, p = line; j < ws; j++, p+=step)
783 			{
784 				*po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]+ 32768)>>16);
785 			}
786 		}
787 		break;
788 	default:
789 		return 0;
790 	}
791 
792 	return 1;
793 
794 }
795 
796 
797 template <class Uint> int
798 
799 #if !defined(_MSC_VER) || _MSC_VER > 1200
800 GLTexInput::
801 #endif
802 
DownSamplePixelDataI2F(unsigned int gl_format,int width,int height,int ds,const Uint * pin,float * pout,int skip)803 DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, int ds,
804 									const Uint * pin, float * pout, int skip)
805 {
806 	int step, linestep;
807 	int i, j;
808 	int ws = width/ds - skip;
809 	int hs = height/ds;
810 	const Uint * line = pin, * p;
811 	float *po = pout;
812     const float factor = (sizeof(Uint) == 1? 255.0f : 65535.0f);
813 	switch(gl_format)
814 	{
815 	case GL_LUMINANCE:
816 	case GL_LUMINANCE_ALPHA:
817 		step = ds * (gl_format == GL_LUMINANCE? 1: 2);
818 		linestep = width * step;
819 		for(i = 0 ; i < hs; i++, line+=linestep)
820 		{
821 			for(j = 0, p = line; j < ws; j++, p+=step)
822 			{
823 				*po++ = (*p) / factor;
824 			}
825 		}
826 		break;
827 	case GL_RGB:
828 	case GL_RGBA:
829 		step = ds * (gl_format == GL_RGB? 3: 4);
830 		linestep = width * step;
831 
832 		for(i = 0 ; i < hs; i++, line+=linestep)
833 		{
834 			for(j = 0, p = line; j < ws; j++, p+=step)
835 			{
836 				//*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5);
837 				*po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]) / (65535.0f * factor));
838 			}
839 		}
840 		break;
841 	case GL_BGR:
842 	case GL_BGRA:
843 		step = ds * (gl_format == GL_BGR? 3: 4);
844 		linestep = width * step;
845 		for(i = 0 ; i < hs; i++, line+=linestep)
846 		{
847 			for(j = 0, p = line; j < ws; j++, p+=step)
848 			{
849 				*po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]) / (65535.0f * factor));
850 			}
851 		}
852 		break;
853 	default:
854 		return 0;
855 	}
856 	return 1;
857 }
858 
DownSamplePixelDataF(unsigned int gl_format,int width,int height,int ds,const float * pin,float * pout,int skip)859 int GLTexInput::DownSamplePixelDataF(unsigned int gl_format, int width, int height, int ds, const float * pin, float * pout, int skip)
860 {
861 	int step, linestep;
862 	int i, j;
863 	int ws = width/ds - skip;
864 	int hs = height/ds;
865 	const float * line = pin, * p;
866 	float *po = pout;
867 	switch(gl_format)
868 	{
869 	case GL_LUMINANCE:
870 	case GL_LUMINANCE_ALPHA:
871 		step = ds * (gl_format == GL_LUMINANCE? 1: 2);
872 		linestep = width * step;
873 		for(i = 0 ; i < hs; i++, line+=linestep)
874 		{
875 			for(j = 0, p = line; j < ws; j++, p+=step)
876 			{
877 				*po++ = *p;
878 			}
879 		}
880 		break;
881 	case GL_RGB:
882 	case GL_RGBA:
883 		step = ds * (gl_format == GL_RGB? 3: 4);
884 		linestep = width * step;
885 		for(i = 0 ; i < hs; i++, line+=linestep)
886 		{
887 			for(j = 0, p = line; j < ws; j++, p+=step)
888 			{
889 				*po++ = (0.299f*p[0] + 0.587f*p[1] + 0.114f*p[2]);
890 			}
891 		}
892 		break;
893 	case GL_BGR:
894 	case GL_BGRA:
895 		step = ds * (gl_format == GL_BGR? 3: 4);
896 		linestep = width * step;
897 		for(i = 0 ; i < hs; i++, line+=linestep)
898 		{
899 			for(j = 0, p = line; j < ws; j++, p+=step)
900 			{
901 				*po++ = (0.114f*p[0] + 0.587f*p[1] + 0.299f * p[2]);
902 			}
903 		}
904 		break;
905 	default:
906 		return 0;
907 	}
908 
909 	return 1;
910 
911 }
912 
SetImageData(int width,int height,const void * data,unsigned int gl_format,unsigned int gl_type)913 int GLTexInput::SetImageData( int width,  int height, const void * data,
914 							 unsigned int gl_format, unsigned int gl_type )
915 {
916 	int simple_format = IsSimpleGlFormat(gl_format, gl_type);//no cpu code to handle other formats
917 	int ws, hs, done = 1;
918 
919 	if(_converted_data) {delete [] _converted_data; _converted_data  = NULL; }
920 
921 	_rgb_converted = 1;
922     _data_modified = 0;
923 
924 	if( simple_format
925 		&& ( width > _texMaxDim || height > _texMaxDim || GlobalUtil::_PreProcessOnCPU)
926 		&& GlobalUtil::_octave_min_default >0   )
927 	{
928 		_down_sampled = GlobalUtil::_octave_min_default;
929 		ws = width >> GlobalUtil::_octave_min_default;
930 		hs = height >> GlobalUtil::_octave_min_default;
931 	}else
932 	{
933 		_down_sampled = 0;
934 		ws = width;
935 		hs = height;
936 	}
937 
938 	if ( ws > _texMaxDim || hs > _texMaxDim)
939 	{
940 		if(simple_format)
941 		{
942 			if(GlobalUtil::_verbose) std::cout<<"Automatic down-sampling is used\n";
943 			do
944 			{
945 				_down_sampled ++;
946 				ws >>= 1;
947 				hs >>= 1;
948 			}while(ws > _texMaxDim || hs > _texMaxDim);
949 		}else
950 		{
951 			std::cerr<<"Input images is too big to fit into a texture\n";
952 			return 0;
953 		}
954 	}
955 
956 	_texWidth = _imgWidth = _drawWidth = ws;
957 	_texHeight = _imgHeight = _drawHeight = hs;
958 
959 	if(GlobalUtil::_verbose)
960 	{
961 		std::cout<<"Image size :\t"<<width<<"x"<<height<<"\n";
962 		if(_down_sampled >0) 	std::cout<<"Down sample to \t"<<ws<<"x"<<hs<<"\n";
963 	}
964 
965 
966     if(GlobalUtil::_UseCUDA || GlobalUtil::_UseOpenCL)
967     {
968         //////////////////////////////////////
969         int tWidth = TruncateWidthCU(_imgWidth);
970         int skip = _imgWidth - tWidth;
971         //skip = 0;
972         if(!simple_format)
973         {
974             std::cerr << "Input format not supported under current settings.\n";
975             return 0;
976         }else if(_down_sampled > 0 || gl_format != GL_LUMINANCE || gl_type != GL_FLOAT)
977         {
978 		    _converted_data = new float [_imgWidth * _imgHeight];
979             if(gl_type == GL_UNSIGNED_BYTE)
980 		        DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
981                                         ((const unsigned char*) data), _converted_data, skip);
982 	        else if(gl_type == GL_UNSIGNED_SHORT)
983 		        DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled,
984                                         ((const unsigned short*) data), _converted_data, skip);
985 	        else
986 		        DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, _converted_data, skip);
987             _rgb_converted = 2;  //indidates a new data copy
988             _pixel_data = _converted_data;
989         }else
990         {
991             //Luminance data that doesn't need to down sample
992             _rgb_converted = 1;
993             _pixel_data = data;
994             if(skip > 0)
995             {
996                 for(int i = 1; i < _imgHeight; ++i)
997                 {
998                     float * dst = ((float*)data) + i * tWidth, * src = ((float*)data) + i * _imgWidth;
999                     for(int j = 0; j < tWidth; ++j) *dst++ = * src++;
1000                 }
1001             }
1002         }
1003         _texWidth = _imgWidth = _drawWidth = tWidth;
1004         _data_modified = 1;
1005     }else
1006     {
1007 	    if(_texID ==0)		glGenTextures(1, &_texID);
1008 	    glBindTexture(_texTarget, _texID);
1009 	    CheckErrorsGL("glBindTexture");
1010 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1011 		glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1012 	    glPixelStorei(GL_UNPACK_ALIGNMENT , 1);
1013 
1014 	    if(simple_format && ( _down_sampled> 0 || (gl_format != GL_LUMINANCE && GlobalUtil::_PreProcessOnCPU) ))
1015 	    {
1016 
1017 		    if(gl_type == GL_UNSIGNED_BYTE)
1018 		    {
1019 			    unsigned char * newdata = new unsigned char [_imgWidth * _imgHeight];
1020 			    DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned char*) data), newdata);
1021 			    glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed
1022                     _imgWidth, _imgHeight, 0,
1023 					GL_LUMINANCE, GL_UNSIGNED_BYTE, newdata);
1024 			    delete[] newdata;
1025 		    }else if(gl_type == GL_UNSIGNED_SHORT)
1026 		    {
1027 			    unsigned short * newdata = new unsigned short [_imgWidth * _imgHeight];
1028 			    DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned short*) data), newdata);
1029 
1030 			    glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,   //internal format changed
1031                     _imgWidth, _imgHeight, 0,
1032 					GL_LUMINANCE, GL_UNSIGNED_SHORT, newdata);
1033 			    delete[] newdata;
1034 		    }else if(gl_type == GL_FLOAT)
1035 		    {
1036 			    float * newdata = new float [_imgWidth * _imgHeight];
1037 			    DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, newdata);
1038 			    glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed
1039                     _imgWidth, _imgHeight, 0,
1040 					GL_LUMINANCE, GL_FLOAT, newdata);
1041 			    delete[] newdata;
1042 		    }else
1043 		    {
1044 			    //impossible
1045 			    done = 0;
1046 			    _rgb_converted = 0;
1047 		    }
1048 		    GlobalUtil::FitViewPort(1, 1);  //this used to be necessary
1049 	    }else
1050 	    {
1051 		    //ds must be 0 here if not simpleformat
1052 		    if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA)
1053             {
1054                 //use one channel internal format if data is intensity image
1055                 glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB,
1056                 _imgWidth, _imgHeight, 0, gl_format,	gl_type, data);
1057 			    GlobalUtil::FitViewPort(1, 1); //this used to be necessary
1058             }
1059 		    else
1060             {
1061 	    	    //convert RGB 2 GRAY if needed
1062                 glTexImage2D(_texTarget, 0,  _iTexFormat, _imgWidth, _imgHeight, 0, gl_format, gl_type, data);
1063                 if(ShaderMan::HaveShaderMan())
1064 			        TexConvertRGB();
1065 		        else
1066 			        _rgb_converted = 0;  //In CUDA mode, the conversion will be done by CUDA kernel
1067             }
1068 	    }
1069 	    UnbindTex();
1070     }
1071 	return done;
1072 }
1073 
1074 
~GLTexInput()1075 GLTexInput::~GLTexInput()
1076 {
1077     if(_converted_data) delete [] _converted_data;
1078 }
1079 
1080 
LoadImageFile(char * imagepath,int & w,int & h)1081 int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h )
1082 {
1083 #ifndef SIFTGPU_NO_DEVIL
1084     static int devil_loaded = 0;
1085 	unsigned int imID;
1086 	int done = 1;
1087 
1088     if(devil_loaded == 0)
1089     {
1090 	    ilInit();
1091 	    ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
1092 	    ilEnable(IL_ORIGIN_SET);
1093         devil_loaded = 1;
1094     }
1095 
1096 	///
1097 	ilGenImages(1, &imID);
1098 	ilBindImage(imID);
1099 
1100 	if(ilLoadImage(imagepath))
1101 	{
1102 		w = ilGetInteger(IL_IMAGE_WIDTH);
1103 		h = ilGetInteger(IL_IMAGE_HEIGHT);
1104 		int ilformat = ilGetInteger(IL_IMAGE_FORMAT);
1105 
1106 		if(SetImageData(w, h, ilGetData(), ilformat, GL_UNSIGNED_BYTE)==0)
1107 		{
1108 			done =0;
1109 		}else 	if(GlobalUtil::_verbose)
1110 		{
1111 			std::cout<<"Image loaded :\t"<<imagepath<<"\n";
1112 		}
1113 
1114 	}else
1115 	{
1116 		std::cerr<<"Unable to open image [code = "<<ilGetError()<<"]\n";
1117 		done = 0;
1118 	}
1119 
1120 	ilDeleteImages(1, &imID);
1121 
1122 	return done;
1123 #else
1124 	FILE * file = fopen(imagepath, "rb"); if (file ==NULL) return 0;
1125 
1126 	char buf[8];	int  width, height, cn, g, done = 1;
1127 
1128 	if(fscanf(file, "%s %d %d %d", buf, &width, &height, &cn )<4 ||  cn > 255 || width < 0 || height < 0)
1129 	{
1130 		fclose(file);
1131         std::cerr << "ERROR: fileformat not supported\n";
1132 		return 0;
1133 	}else
1134     {
1135         w = width;
1136         h = height;
1137     }
1138     unsigned char * data = new unsigned char[width * height];
1139 	unsigned char * pixels = data;
1140 	if (strcmp(buf, "P5")==0 )
1141 	{
1142 		fscanf(file, "%c",buf);//skip one byte
1143 		fread(pixels, 1, width*height, file);
1144 	}else if (strcmp(buf, "P2")==0 )
1145 	{
1146 		for (int i = 0 ; i< height; i++)
1147 		{
1148 			for ( int j = 0; j < width; j++)
1149 			{
1150 				fscanf(file, "%d", &g);
1151 				*pixels++ = (unsigned char) g;
1152 			}
1153 		}
1154 	}else if (strcmp(buf, "P6")==0 )
1155 	{
1156 		fscanf(file, "%c", buf);//skip one byte
1157 		int j, num = height*width;
1158         unsigned char buf[3];
1159 		for ( j =0 ; j< num; j++)
1160 		{
1161 			fread(buf,1,3, file);
1162 			*pixels++=int(0.10454f* buf[2]+0.60581f* buf[1]+0.28965f* buf[0]);
1163 		}
1164 	}else if (strcmp(buf, "P3")==0 )
1165 	{
1166 		int r, g, b;
1167 		int i , num =height*width;
1168 		for ( i = 0 ; i< num; i++)
1169 		{
1170 			fscanf(file, "%d %d %d", &r, &g, &b);
1171 			*pixels++ = int(0.10454f* b+0.60581f* g+0.28965f* r);
1172 		}
1173 
1174 	}else
1175 	{
1176         std::cerr << "ERROR: fileformat not supported\n";
1177 		done = 0;
1178 	}
1179     if(done)    SetImageData(width, height, data, GL_LUMINANCE, GL_UNSIGNED_BYTE);
1180 	fclose(file);
1181     delete data;
1182     if(GlobalUtil::_verbose && done) std::cout<< "Image loaded :\t" << imagepath << "\n";
1183 	return 1;
1184 #endif
1185 }
1186 
CopyToPBO(GLuint pbo,int width,int height,GLenum format)1187 int GLTexImage::CopyToPBO(GLuint pbo, int width, int height, GLenum format)
1188 {
1189     /////////
1190     if(format != GL_RGBA && format != GL_LUMINANCE) return 0;
1191 
1192 	FrameBufferObject fbo;
1193     GLint bsize, esize = width * height * sizeof(float) * (format == GL_RGBA ? 4 : 1);
1194 	AttachToFBO(0);
1195 	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
1196 	glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
1197 	if(bsize < esize)
1198 	{
1199 		glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize,	NULL, GL_STATIC_DRAW_ARB);
1200 		glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize);
1201 	}
1202 	if(bsize >= esize)
1203 	{
1204 		glReadPixels(0, 0, width, height, format, GL_FLOAT, 0);
1205 	}
1206 	glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
1207 	DetachFBO(0);
1208 
1209 	return bsize >= esize;
1210 }
1211 
SaveToASCII(const char * path)1212 void GLTexImage::SaveToASCII(const char* path)
1213 {
1214 	vector<float> buf(GetImgWidth() * GetImgHeight() * 4);
1215 	FrameBufferObject fbo;
1216 	AttachToFBO(0);
1217 	glReadPixels(0, 0, GetImgWidth(), GetImgHeight(), GL_RGBA, GL_FLOAT, &buf[0]);
1218 	ofstream out(path);
1219 
1220 	for(int i = 0, idx = 0; i < GetImgHeight(); ++i)
1221 	{
1222 		for(int j = 0; j < GetImgWidth(); ++j, idx += 4)
1223 		{
1224 			out << i << " " << j << " " << buf[idx] << " " << buf[idx + 1] << " "
1225 				<< buf[idx + 2] <<  " " << buf[idx + 3] << "\n";
1226 		}
1227 	}
1228 }
1229 
1230 
VerifyTexture()1231 void GLTexInput::VerifyTexture()
1232 {
1233     //for CUDA or OpenCL the texture is not generated by default
1234     if(!_data_modified) return;
1235     if(_pixel_data== NULL) return;
1236     InitTexture(_imgWidth, _imgHeight);
1237     BindTex();
1238 	glTexImage2D(   _texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed
1239                     _imgWidth, _imgHeight, 0,
1240 					GL_LUMINANCE, GL_FLOAT, _pixel_data);
1241     UnbindTex();
1242     _data_modified = 0;
1243 }
1244 
CopyFromPBO(GLuint pbo,int width,int height,GLenum format)1245 void GLTexImage::CopyFromPBO(GLuint pbo, int width, int height, GLenum format)
1246 {
1247 	InitTexture(max(width, _texWidth), max(height, _texHeight));
1248 	SetImageSize(width, height);
1249 	if(width > 0 && height > 0)
1250 	{
1251 		BindTex();
1252 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
1253 		glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, width, height, format, GL_FLOAT, 0);
1254         GlobalUtil::CheckErrorsGL("GLTexImage::CopyFromPBO->glTexSubImage2D");
1255 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1256 		UnbindTex();
1257 	}
1258 }
1259 
1260