Added image view module

This commit is contained in:
eddyem 2015-02-18 18:56:59 +03:00
parent c14be0eb90
commit bf7a247678
16 changed files with 1376 additions and 25 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
*.bck *.bck
*.o *.o
.hg* .hg*
.dropbox.attr

View File

@ -22,23 +22,11 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
# add_definitions(-DSOME_DEFS) # add_definitions(-DSOME_DEFS)
#endif() #endif()
# cmake -DDEBUG=1 -> debugging # cmake -DEBUG=1 -> debugging
if(DEFINED DEBUG) if(DEFINED EBUG)
add_definitions(-DEBUG) add_definitions(-DEBUG)
endif() endif()
# directory should contain dir locale/ru for gettext translations
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
if(NOT DEFINED LOCALEDIR)
if(DEFINED DEBUG)
set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale)
else()
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
endif()
endif()
# gettext modules
set(MODULES libavformat libavcodec libswscale libavutil libavdevice) set(MODULES libavformat libavcodec libswscale libavutil libavdevice)
# additional modules on condition # additional modules on condition
#if(DEFINED SOMETHING) #if(DEFINED SOMETHING)
@ -54,6 +42,17 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES
endif() endif()
message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
# directory should contain dir locale/ru for gettext translations
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
if(NOT DEFINED LOCALEDIR)
if(DEFINED DEBUG)
set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale)
else()
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
endif()
endif()
# gettext files # gettext files
set(PO_FILE ${LCPATH}/messages.po) set(PO_FILE ${LCPATH}/messages.po)
set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo)
@ -61,26 +60,46 @@ set(RU_FILE ${LCPATH}/ru.po)
# pkgconfig # pkgconfig
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(${PROJ} REQUIRED ${MODULES}) #find_package(OpenGL REQUIRED)
#find_package(GTK2 REQUIRED)
# etc
# set(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} )
# set(${${PROJ}_LIBRARY_DIRS} ...)
if(MODULES)
pkg_check_modules(${PROJ} REQUIRED ${MODULES})
endif()
#OpenMP
#include(FindOpenMP)
#if(OPENMP_FOUND)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
#endif()
# exe file # exe file
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE}) add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES}) target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} ${OPENGL_LIBRARIES} ...)
include_directories(${${PROJ}_INCLUDE_DIRS}) include_directories(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ...)
link_directories(${${PROJ}_LIBRARY_DIRS}) link_directories(${${PROJ}_LIBRARY_DIRS} )
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\" -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\" -DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
-DMAJOR_VERSION=\"${MAJOR_VESION}\") -DMAJOR_VERSION=\"${MAJOR_VESION}\")
# Installation of the program # Installation of the program
INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES") if(NOT DEFINED DEBUG)
#PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES")
INSTALL(TARGETS ${PROJ} DESTINATION "bin") #PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
#PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) INSTALL(TARGETS ${PROJ} DESTINATION "bin")
# Script to be executed at installation time (kind of post-intallation script) to #PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
# change the right accesses on the installed files # Script to be executed at installation time (kind of post-intallation script) to
#INSTALL(SCRIPT inst.cmake) # change the right accesses on the installed files
#INSTALL(SCRIPT inst.cmake)
else()
install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")")
endif(NOT DEFINED DEBUG)
find_package(Gettext REQUIRED) find_package(Gettext REQUIRED)
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)

View File

@ -0,0 +1,136 @@
cmake_minimum_required(VERSION 2.8)
# cmake -DEBUG=1 -> debugging
if(DEFINED EBUG)
add_definitions(-DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
set(PROJ openglview)
set(MINOR_VERSION "1")
set(MID_VERSION "0")
set(MAJOR_VERSION "0")
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
message("VER: ${VERSION}")
# default flags
set(CFLAGS -O2 -Wextra -Wall -Werror -W -std=gnu99)
set(CMAKE_COLOR_MAKEFILE ON)
# here is one of two variants: all .c in directory or .c files in list
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
#set(SOURCES list_of_c_files)
# we can change file list
#if(NOT DEFINED something)
# set(SOURCES ${SOURCES} one_more_list)
# add_definitions(-DSOME_DEFS)
#endif()
set(MODULES)
# additional modules on condition
#if(DEFINED SOMETHING)
# set(MODULES ${MODULES} more_modules>=version)
# add_definitions(-DSOMEDEFS)
#endif()
project(${PROJ})
# change wrong behaviour with install prefix
if(CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
message("Change default install path to /usr")
set(CMAKE_INSTALL_PREFIX "/usr")
endif()
message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
if(NOT DEFINED NOGETTEXT)
# directory should contain dir locale/ru for gettext translations
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
if(NOT DEFINED LOCALEDIR)
if(DEFINED DEBUG)
set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale)
else()
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
endif()
endif()
# gettext files
set(PO_FILE ${LCPATH}/messages.po)
set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo)
set(RU_FILE ${LCPATH}/ru.po)
else()
add_definitions(-DNOGETTEXT)
set(PO_FILE)
set(MO_FILE)
endif()
# pkgconfig
find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(JPEG REQUIRED)
if(MODULES)
pkg_check_modules(${PROJ} REQUIRED ${MODULES})
endif()
#OpenMP
#include(FindOpenMP)
#if(OPENMP_FOUND)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
#endif()
# exe file
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} ${OPENGL_LIBRARIES} ${JPEG_LIBRARIES}
${GLUT_LIBRARIES} -lm -lpthread)
include_directories(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${GLUT_INCLUDE_DIR})
link_directories(${${PROJ}_LIBRARY_DIRS})
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
-DMAJOR_VERSION=\"${MAJOR_VESION}\" -DPROJNAME=\"${PROJ}\")
# Installation of the program
if(NOT DEFINED DEBUG)
INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES")
#PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
INSTALL(TARGETS ${PROJ} DESTINATION "bin")
#PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
# Script to be executed at installation time (kind of post-intallation script) to
# change the right accesses on the installed files
#INSTALL(SCRIPT inst.cmake)
else()
install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")")
endif(NOT DEFINED DEBUG)
if(NOT DEFINED NOGETTEXT)
find_package(Gettext REQUIRED)
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
if(NOT GETTEXT_XGETTEXT_EXECUTABLE OR NOT GETTEXT_MSGFMT_EXECUTABLE)
message(FATAL_ERROR "xgettext not found")
endif()
file(MAKE_DIRECTORY ${LCPATH})
file(MAKE_DIRECTORY ${LCPATH}/LC_MESSAGES)
add_custom_command(
OUTPUT ${PO_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=utf-8 ${SOURCES} -c -k_ -kN_ -o ${PO_FILE}
COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE}
COMMAND enconv ${PO_FILE}
DEPENDS ${SOURCES}
)
# we need this to prewent ru.po from deleting by make clean
add_custom_target(
RU_FILE
COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE}
DEPENDS ${PO_FILE}
)
add_custom_command(
OUTPUT ${MO_FILE}
COMMAND make RU_FILE && ${GETTEXT_MSGFMT_EXECUTABLE} ${RU_FILE} -o ${MO_FILE}
DEPENDS ${PO_FILE}
)
endif(NOT DEFINED NOGETTEXT)

189
image_view_module/bmpview.c Normal file
View File

@ -0,0 +1,189 @@
// bmpview.c
//
// Copyright 2010 Edward V. Emelianoff <eddy@sao.ru>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//-lglut
#include "bmpview.h"
#include "macros.h"
#include <pthread.h>
int totWindows = 0; // total number of opened windows
/*
void *GLloop(){
FNAME();
glutMainLoop();
return NULL;
}*/
/**
* create window & run main loop
*/
void createWindow(windowData *win){
FNAME();
if(!win) return;
int w = win->w, h = win->h;
/*
char *argv[] = {PROJNAME, NULL};
int argc = 1;
glutInit(&argc, argv);
*/
glGenTextures(1, &(win->Tex));
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(w, h);
win->GL_ID = glutCreateWindow(win->title);
DBG("created GL_ID=%d", win->GL_ID);
glutIdleFunc(Redraw);
glutReshapeFunc(Resize);
glutDisplayFunc(RedrawWindow);
glutKeyboardFunc(keyPressed);
glutSpecialFunc(keySpPressed);
glutMouseFunc(mousePressed);
glutMotionFunc(mouseMove);
win->z = 0.;
createMenu(win->ID);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, win->Tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, win->rawdata);
glDisable(GL_TEXTURE_2D);
totWindows++;
}
/*
void showid(int id){
printf("ID: %d\n", id);
}
*/
/**
* destroy window with OpenGL or inner identificator "window"
* @param window inner or OpenGL id
* @param idtype = INNER or OPENGL
* @return 1 in case of OK, 0 if fault
*/
int destroyWindow(int window, winIdType type){
windowData *win;
int canceled = 1;
if(type == OPENGL)
win = searchWindow_byGLID(window);
else
win = searchWindow(window);
if(!win) return 0;
//forEachWindow(showid);
pthread_mutex_lock(&win->mutex);
if(!pthread_cancel(win->thread)){ // cancel thread changing data
canceled = 0;
}
pthread_join(win->thread, NULL);
glDeleteTextures(1, &win->Tex);
glFinish();
glutDestroyWindow(win->GL_ID);
win->GL_ID = 0; // reset for forEachWindow()
pthread_mutex_unlock(&win->mutex);
if(!canceled && !pthread_cancel(win->thread)){ // cancel thread changing data
WARN(_("can't cancel a thread!"));
}
pthread_join(win->thread, NULL);
if(!removeWindow(win->ID)) WARNX(_("Error removing from list"));
totWindows--;
//forEachWindow(showid);
return 1;
}
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){
char *c;
int x1=x, W=0;
for(c = string; *c; c++){
W += glutBitmapWidth(font,*c);// + 1;
}
x1 -= W/2;
glColor3ubv(color);
glLoadIdentity();
glTranslatef(0.,0., -150);
//glTranslatef(x,y, -4000.);
for (c = string; *c != '\0'; c++){
glColor3ubv(color);
glRasterPos2f(x1,y);
glutBitmapCharacter(font, *c);
//glutStrokeCharacter(GLUT_STROKE_ROMAN, *c);
x1 = x1 + glutBitmapWidth(font,*c);// + 1;
}
}
void redisplay(int GL_ID){
glutSetWindow(GL_ID);
glutPostRedisplay();
}
void Redraw(){
forEachWindow(redisplay);
usleep(10000);
}
void RedrawWindow(){
int window;
window = glutGetWindow();
windowData *win = searchWindow_byGLID(window);
if(!win) return;
if(pthread_mutex_trylock(&win->mutex) != 0) return;
/* Clear the windwindowDataow to black */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-win->w/2.,-win->h/2., win->z);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, win->Tex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win->w, win->h, GL_RGB, GL_UNSIGNED_BYTE, win->rawdata);
glBegin(GL_QUADS);
glTexCoord2f(0., 1.); glVertex3f(0., 0., 0.);
glTexCoord2f(0., 0.); glVertex3f(0., win->h, 0.);
glTexCoord2f(1., 0.); glVertex3f(win->w, win->h, 0.);
glTexCoord2f(1., 1.); glVertex3f(win->w, 0., 0.);
glEnd();
glDisable(GL_TEXTURE_2D);
glFinish();
glutSwapBuffers();
pthread_mutex_unlock(&win->mutex);
}
void Resize(int width, int height){
FNAME();
int window = glutGetWindow();
windowData *win = searchWindow_byGLID(window);
if(!win) return;
int GRAB_WIDTH = win->w, GRAB_HEIGHT = win->h;
float _U_ tmp, wd = (float) width/GRAB_WIDTH, ht = (float)height/GRAB_HEIGHT;
tmp = (wd + ht) / 2.;
width = (int)(tmp * GRAB_WIDTH); height = (int)(tmp * GRAB_HEIGHT);
glutReshapeWindow(width, height);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat W = (GLfloat)GRAB_WIDTH; GLfloat H = (GLfloat)GRAB_HEIGHT;
//glOrtho(-W,W, -H,H, -1., 1.);
gluPerspective(90., W/H, 0., 100.0);
gluLookAt(0., 0., H/2., 0., 0., 0., 0., 1., 0.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

View File

@ -0,0 +1,43 @@
/*
* bmpview.h
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __BMPVIEW_H__
#define __BMPVIEW_H__
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "events.h"
#include "list.h"
typedef enum{
INNER,
OPENGL
} winIdType;
void createWindow(windowData *win);
int destroyWindow(int window, winIdType type);
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color);
void Redraw();
void RedrawWindow();
void Resize(int width, int height);
#endif // __BMPVIEW_H__

101
image_view_module/events.c Normal file
View File

@ -0,0 +1,101 @@
/*
* events.c
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "events.h"
#include "bmpview.h"
#include "macros.h"
/*
* æÕÎËÃÉÉ ÄÌÑ ÒÁÂÏÔÙ Ó OpenGL'ÎÙÍÉ ÓÏÂÙÔÉÑÍÉ
*/
int ShowWavelet = 0;
void keyPressed(unsigned char key, // ËÏÄ ××ÅÄÅÎÎÏÇÏ ÓÉÍ×ÏÌÁ
_U_ int x, _U_ int y){ // ËÏÏÒÄÉÎÁÔÙ ÍÙÛÉ ÐÒÉ ÎÁÖÁÔÉÉ ËÌÁ×ÉÛÉ
int _U_ mod = glutGetModifiers(), window = glutGetWindow();
windowData *win = searchWindow_byGLID(window);
if(!win) return;
//DBG("Key pressed. mod=%d, keycode=%d, point=(%d,%d)\n", mod, key, x,y);
if((mod == GLUT_ACTIVE_CTRL) && (key == 'q' || key == 17)) exit(0); // ctrl + q
switch(key){
// case 'i': more_info = !more_info;
// break;
case 27: destroyWindow(window, OPENGL);
break;
case 'p':
printf("z = %f\n", win->z);
break;
// case 'm': createWindow(&mainWindow);
// break;
// case 'w': createWindow(&WaveWindow);
// break;
case 'Z': win->z += 1.0;
break;
case 'z': win->z -= 1.0;
break;
// case 'h': createWindow(&SubWindow);
// break;
}
}
void keySpPressed(_U_ int key, _U_ int x, _U_ int y){
// int mod = glutGetModifiers();
DBG("Sp. key pressed. mod=%d, keycode=%d, point=(%d,%d)\n", glutGetModifiers(), key, x,y);
}
void mousePressed(int _U_ key, int _U_ state, _U_ int x, _U_ int y){
// GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
DBG("Mouse button %s. point=(%d, %d); mod=%d, button=%d\n",
(state == GLUT_DOWN)? "pressed":"released", x, y, glutGetModifiers(), key);
/* int window = glutGetWindow();
if(window == WaveWindow){ // ÝÅÌËÎÕÌÉ × ÏËÎÅ Ó ×ÅÊ×ÌÅÔÏÍ
_U_ int w = glutGet(GLUT_WINDOW_WIDTH) / 2;
_U_ int h = glutGet(GLUT_WINDOW_HEIGHT) / 2;
if(state == GLUT_DOWN && key == GLUT_LEFT_BUTTON){
//HistCoord[0] = (x > w);
//HistCoord[1] = (y > h);
}
}
*/
}
void mouseMove(_U_ int x, _U_ int y){
DBG("Mouse moved to (%d, %d)\n", x, y);
}
/**
* winID - inner !!!
*/
void createMenu(_U_ int winID){
glutCreateMenu(menuEvents);
glutAddMenuEntry("Quit (ctrl+q)", 'q');
glutAddMenuEntry("Close this window (ESC)", 27);
// if(window == &mainWindow){ // ÐÕÎËÔÙ ÍÅÎÀ ÇÌÁ×ÎÏÇÏ ÏËÎÁ
glutAddMenuEntry("Info in stderr (i)", 'i');
// }
;
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void menuEvents(int opt){
if(opt == 'q') exit(0);
keyPressed((unsigned char)opt, 0, 0);
}

View File

@ -0,0 +1,41 @@
/*
* events.h
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __EVENTS_H__
#define __EVENTS_H__
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/glext.h>
extern float Z; // ËÏÏÒÄÉÎÁÔÁ Z (zoom)
void keyPressed(unsigned char key, int x, int y);
void keySpPressed(int key, int x, int y);
void mousePressed(int key, int state, int x, int y);
void mouseMove(int x, int y);
void createMenu(int window);
void menuEvents(int opt);
#endif // __EVENTS_H__

182
image_view_module/list.c Normal file
View File

@ -0,0 +1,182 @@
/*
* simple_list.c - simple one-direction list
*
*
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "list.h"
#include "macros.h"
typedef struct list_{
windowData *data;
struct list_ *next;
struct list_ *prev;
} WinList;
static WinList *root = NULL;
/**
* add element v to list with root root (also this can be last element)
* @param root (io) - pointer to root (or last element) of list or NULL
* if *root == NULL, just created node will be placed there
* IDs in list are sorted, so if root's ID isn't 0, it will be moved
* @param w - data inserted (with empty ID - identificator will be assigned here)
* @return pointer to data inside created node or NULL
*/
windowData *addWindow(windowData *w){
WinList *node, *last, *curr;
int freeID = 1, curID;
if((node = MALLOC(WinList, 1)) == 0) return NULL; // allocation error
node->data = w; // insert data
if(root){ // there was root node - search last
last = root;
if(last->data->ID != 0){ // root element have non-zero ID
node->next = last;
root->prev = node;
root = NULL;
}else{ // root element have ID==0, search first free ID
while((curr = last->next)){
if((curID = curr->data->ID) > freeID) // we found a hole!
break;
else
freeID = curID + 1;
last = last->next;
}
last->next = node; // insert pointer to new node into last element in list
node->prev = last; // don't forget a pointer to previous element
node->next = curr; // next item after a hole or NULL if there isn't holes
w->ID = freeID;
}
}
if(!root){ // we need to change root to this element; (*root=NULL could be done upper)
root = node;
w->ID = 0;
}
DBG("added window with id = %d", w->ID);
return w;
}
/**
* search window with given inner identificator winID
* @return pointer to window struct or NULL if not found
*/
WinList *searchWindowList(int winID){
WinList *node = NULL, *next = root;
int curID;
if(!root){
DBG("no root leaf");
return NULL;
}
do{
node = next;
next = node->next;
curID = node->data->ID;
}while(curID < winID && next);
if(curID != winID) return NULL;
return node;
}
/**
* the same as upper but for outern usage
*/
windowData *searchWindow(int winID){
WinList *node = searchWindowList(winID);
if(!node) return NULL;
return node->data;
}
/**
* search window with given OpenGL identificator GL_ID
* @return pointer to window struct or NULL if not found
*/
windowData *searchWindow_byGLID(int GL_ID){
WinList *node = NULL, *next = root;
int curID;
if(!root) return NULL;
do{
node = next;
next = node->next;
curID = node->data->GL_ID;
}while(curID != GL_ID && next);
if(curID != GL_ID) return NULL;
return node->data;
}
/**
* free() all data for node of list
* !!! data for raw pixels (rawdata) doesn't removed as it should be used
* only for initialisation and free() by user !!!
*/
void WinList_freeNode(WinList **node){
if(!node || !*node) return;
WinList *cur = *node, *prev = cur->prev, *next = cur->next;
windowData *win = cur->data;
if(root == cur) root = next;
FREE(win->title);
FREE(win->rawdata);
pthread_mutex_destroy(&win->mutex);
FREE(*node);
if(prev)
prev->next = next;
if(next)
next->prev = prev;
}
/**
* remove window with ID winID
* @return 0 in case of error !0 if OK
*/
int removeWindow(int winID){
WinList *node = searchWindowList(winID);
if(!node){
DBG("Not found");
return 0;
}
DBG("removing win ID=%d", winID);
WinList_freeNode(&node);
return 1;
}
/**
* remove all nodes in list
* @param root - pointer to root node
*/
void freeWinList(){
WinList *node = root, *next;
if(!root) return;
do{
next = node->next;
WinList_freeNode(&node);
node = next;
}while(node);
root = NULL;
}
/**
* run function for each window in list
*/
void forEachWindow(void (*fn)(int GL_ID)){
WinList *node = root;
if(!root) return;
do{
int id = node->data->GL_ID;
if(id) fn(id);
node = node->next;
}while(node);
}

56
image_view_module/list.h Normal file
View File

@ -0,0 +1,56 @@
/*
* simple_list.h - header file for simple list support
* TO USE IT you must define the type of data as
* typedef your_type listdata
* or at compiling time
* -Dlistdata=your_type
* or by changing this file
*
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __SIMPLE_LIST_H__
#define __SIMPLE_LIST_H__
#include "events.h"
typedef struct{
int ID; // identificator
char *title; // title of window
GLuint Tex; // texture for image inside window
int GL_ID; // identificator of OpenGL window
GLubyte *rawdata; // raw image data
int w; int h; // image size
float z; // z-coordinate (zoom)
pthread_t thread; // identificator of thread that changes window data
pthread_mutex_t mutex;// mutex for operations with image
} windowData;
// add element v to list with root root (also this can be last element)
windowData *addWindow(windowData *w);
windowData *searchWindow(int winID);
windowData *searchWindow_byGLID(int winGLID);
void forEachWindow(void (*fn)(int GL_ID));
int removeWindow(int winID);
void freeWinList();
#endif // __SIMPLE_LIST_H__

Binary file not shown.

View File

@ -0,0 +1,57 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-18 18:46+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:175
msgid "No filename given!"
msgstr "îÅ ÕËÁÚÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:177
#, c-format
msgid "Can't open %s for reading"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:179
#, c-format
msgid "Can't stat %s"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat ÄÌÑ %s"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:182
msgid "Mmap error for input"
msgstr "ïÛÉÂËÁ mmap ÄÌÑ ×ÈÏÄÎÙÈ ÄÁÎÎÙÈ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:183
msgid "Can't close mmap'ed file"
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:192
msgid "Can't munmap"
msgstr "îÅ ÍÏÇÕ ×ÙÚÙ×ÁÔØ munmap"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/main.c:106
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÉÒÏ×ÁÔØ ×ÚÁÉÍÎÏÅ ÉÓËÌÀÞÅÎÉÅ!"
#. cancel thread changing data
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:102
msgid "can't cancel a thread!"
msgstr "îÅ ÍÏÇÕ ÏÔÍÅÎÉÔØ ×ÙÐÏÌÎÅÎÉÅ ÐÏÔÏËÁ!"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:105
msgid "Error removing from list"
msgstr "ïÛÉÂËÁ ÕÄÁÌÅÎÉÑ ÉÚ ÓÐÉÓËÁ"

View File

@ -0,0 +1,56 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-18 18:46+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:183
msgid "Can't close mmap'ed file"
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/main.c:106
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÉÒÏ×ÁÔØ ×ÚÁÉÍÎÏÅ ÉÓËÌÀÞÅÎÉÅ!"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:192
msgid "Can't munmap"
msgstr "îÅ ÍÏÇÕ ×ÙÚÙ×ÁÔØ munmap"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:177
#, c-format
msgid "Can't open %s for reading"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:179
#, c-format
msgid "Can't stat %s"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat ÄÌÑ %s"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:105
msgid "Error removing from list"
msgstr "ïÛÉÂËÁ ÕÄÁÌÅÎÉÑ ÉÚ ÓÐÉÓËÁ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:182
msgid "Mmap error for input"
msgstr "ïÛÉÂËÁ mmap ÄÌÑ ×ÈÏÄÎÙÈ ÄÁÎÎÙÈ"
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:175
msgid "No filename given!"
msgstr "îÅ ÕËÁÚÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
#. cancel thread changing data
#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:102
msgid "can't cancel a thread!"
msgstr "îÅ ÍÏÇÕ ÏÔÍÅÎÉÔØ ×ÙÐÏÌÎÅÎÉÅ ÐÏÔÏËÁ!"

195
image_view_module/macros.c Normal file
View File

@ -0,0 +1,195 @@
/*
* usefull_macros.h - a set of usefull functions: memory, color etc
*
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "macros.h"
#include <sys/time.h>
/**
* function for different purposes that need to know time intervals
* @return double value: time in seconds
*/
double dtime(){
double t;
struct timeval tv;
gettimeofday(&tv, NULL);
t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
return t;
}
/******************************************************************************\
* Coloured terminal
\******************************************************************************/
int globErr = 0; // errno for WARN/ERR
// pointers to coloured output printf
int (*red)(const char *fmt, ...);
int (*green)(const char *fmt, ...);
int (*_WARN)(const char *fmt, ...);
/*
* format red / green messages
* name: r_pr_, g_pr_
* @param fmt ... - printf-like format
* @return number of printed symbols
*/
int r_pr_(const char *fmt, ...){
va_list ar; int i;
printf(RED);
va_start(ar, fmt);
i = vprintf(fmt, ar);
va_end(ar);
printf(OLDCOLOR);
return i;
}
int g_pr_(const char *fmt, ...){
va_list ar; int i;
printf(GREEN);
va_start(ar, fmt);
i = vprintf(fmt, ar);
va_end(ar);
printf(OLDCOLOR);
return i;
}
/*
* print red error/warning messages (if output is a tty)
* @param fmt ... - printf-like format
* @return number of printed symbols
*/
int r_WARN(const char *fmt, ...){
va_list ar; int i = 1;
fprintf(stderr, RED);
va_start(ar, fmt);
if(globErr){
errno = globErr;
vwarn(fmt, ar);
errno = 0;
globErr = 0;
}else
i = vfprintf(stderr, fmt, ar);
va_end(ar);
i++;
fprintf(stderr, OLDCOLOR "\n");
return i;
}
const char stars[] = "****************************************";
/*
* notty variants of coloured printf
* name: s_WARN, r_pr_notty
* @param fmt ... - printf-like format
* @return number of printed symbols
*/
int s_WARN(const char *fmt, ...){
va_list ar; int i;
i = fprintf(stderr, "\n%s\n", stars);
va_start(ar, fmt);
if(globErr){
errno = globErr;
vwarn(fmt, ar);
errno = 0;
globErr = 0;
}else
i = +vfprintf(stderr, fmt, ar);
va_end(ar);
i += fprintf(stderr, "\n%s\n", stars);
i += fprintf(stderr, "\n");
return i;
}
int r_pr_notty(const char *fmt, ...){
va_list ar; int i;
i = printf("\n%s\n", stars);
va_start(ar, fmt);
i += vprintf(fmt, ar);
va_end(ar);
i += printf("\n%s\n", stars);
return i;
}
/**
* Run this function in the beginning of main() to setup locale & coloured output
*/
void initial_setup(){
// setup coloured output
if(isatty(STDOUT_FILENO)){ // make color output in tty
red = r_pr_; green = g_pr_;
}else{ // no colors in case of pipe
red = r_pr_notty; green = printf;
}
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
else _WARN = s_WARN;
// Setup locale
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C");
#ifndef NOGETTEXT
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
textdomain(GETTEXT_PACKAGE);
#endif
}
/******************************************************************************\
* Memory
\******************************************************************************/
/*
* safe memory allocation for macro ALLOC
* @param N - number of elements to allocate
* @param S - size of single element (typically sizeof)
* @return pointer to allocated memory area
*/
void *my_alloc(size_t N, size_t S){
void *p = calloc(N, S);
if(!p) ERR("malloc");
//assert(p);
return p;
}
/**
* Mmap file to a memory area
*
* @param filename (i) - name of file to mmap
* @return stuct with mmap'ed file or die
*/
mmapbuf *My_mmap(char *filename){
int fd;
char *ptr;
size_t Mlen;
struct stat statbuf;
if(!filename) ERRX(_("No filename given!"));
if((fd = open(filename, O_RDONLY)) < 0)
ERR(_("Can't open %s for reading"), filename);
if(fstat (fd, &statbuf) < 0)
ERR(_("Can't stat %s"), filename);
Mlen = statbuf.st_size;
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
ERR(_("Mmap error for input"));
if(close(fd)) ERR(_("Can't close mmap'ed file"));
mmapbuf *ret = MALLOC(mmapbuf, 1);
ret->data = ptr;
ret->len = Mlen;
return ret;
}
void My_munmap(mmapbuf *b){
if(munmap(b->data, b->len))
ERR(_("Can't munmap"));
FREE(b);
}

117
image_view_module/macros.h Normal file
View File

@ -0,0 +1,117 @@
/*
* macros.h
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __MACROS_H__
#define __MACROS_H__
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <err.h>
#include <locale.h>
#include <libintl.h>
#include <stdlib.h>
#include <termios.h>
#include <termio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdint.h>
#include <pthread.h>
// not used args
#define _U_ __attribute__((__unused__))
#define check_ptr(ptr, fn) \
if((ptr) == NULL) { \
printf("%10s: NULL pointer\n",(char *)(fn)); \
perror((char *)(fn)); \
exit(1); \
}
#ifdef NOGETTEXT
#ifdef gettext
#undef gettext
#endif
#define gettext(arg) arg
#endif
#define _(String) gettext(String)
#define gettext_noop(String) String
#define N_(String) gettext_noop(String)
/*
* Coloured messages output
*/
#define RED "\033[1;31;40m"
#define GREEN "\033[1;32;40m"
#define OLDCOLOR "\033[0;0;0m"
extern int globErr;
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)
#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); exit(-1);}while(0)
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
/*
* print function name, debug messages
* debug mode, -DEBUG
*/
#ifdef EBUG
#define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
#define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n");} while(0)
#else
#define FNAME() do{}while(0)
#define DBG(...) do{}while(0)
#endif //EBUG
/*
* Memory allocation
*/
#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type)))
#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
#define FREE(ptr) do{free(ptr); ptr = NULL;}while(0)
// functions for color output in tty & no-color in pipes
extern int (*red)(const char *fmt, ...);
extern int (*_WARN)(const char *fmt, ...);
extern int (*green)(const char *fmt, ...);
void * my_alloc(size_t N, size_t S);
void initial_setup();
// mmap file
typedef struct{
char *data;
size_t len;
} mmapbuf;
mmapbuf *My_mmap(char *filename);
void My_munmap(mmapbuf *b);
#endif // __MACROS_H__

152
image_view_module/main.c Normal file
View File

@ -0,0 +1,152 @@
/*
* main.c
*
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <sys/time.h>
#include <stdio.h>
#include <getopt.h>
#include <stdbool.h>
#include <X11/Xlib.h> // XInitThreads();
#include "main.h"
#include "macros.h"
#include "bmpview.h"
//GLubyte *BitmapBits = NULL;
/*
pthread_mutex_t m_ima = PTHREAD_MUTEX_INITIALIZER, m_wvlt = PTHREAD_MUTEX_INITIALIZER,
m_hist = PTHREAD_MUTEX_INITIALIZER;
*/
unsigned int bufsize;
void help(char *s){
fprintf(stderr, "\n\n%s, simple interface for LOMO's webcam \"microscope\"\n", s);
fprintf(stderr, "Usage: %s [-h] [-d videodev] [-c channel]\n\n", s);
fprintf(stderr,
"-h, --help:\tthis help\n"
"-d, --device:\tcapture from <videodev>\n"
"-c, --channel:\tset channel <channel> (0..3)\n"
);
fprintf(stderr, "\n\n");
}
void* change_image(void *data){
FNAME();
windowData *win = (windowData*) data;
int w = win->w, h = win->h, x,y, id = win->ID;
GLubyte i;
DBG("w=%d, h=%d",w,h);
for(i = 1; ;i++){
if(!searchWindow(id)) pthread_exit(NULL);
pthread_mutex_lock(&win->mutex);
GLubyte *raw = win->rawdata;
for(y = 0; y < h; y++){
if(y%20 == 19){
raw += w*3;
continue;
}
for(x = 0; x < w; x++){
if(x%20 != 19){
if(i < 80) raw[0]++;
else if(i < 170) raw[1]++;
else raw[2]++;
}
raw += 3;
}
}
pthread_mutex_unlock(&win->mutex);
usleep(10000);
}
}
/*
void *GLloop(void *data){
FNAME();
windowData *win = (windowData *)data;
createWindow(win);
return NULL;
}
*/
/**
* create new window, run thread & return pointer to its structure or NULL
* @param title - header (copyed inside this function)
* @param w,h - image size
*/
windowData *createGLwin(char *title, int w, int h){
windowData *win = MALLOC(windowData, 1);
if(!addWindow(win)){
FREE(win);
return NULL;
}
GLubyte *raw = MALLOC(GLubyte, w*h*3);
win->title = strdup(title);
win->rawdata = raw;
if(pthread_mutex_init(&win->mutex, NULL)){
WARN(_("Can't init mutex!"));
removeWindow(win->ID);
return NULL;
}
win->w = w;
win->h = h;
// pthread_create(&win->glthread, NULL, GLloop, (void*)win);
createWindow(win);
return win;
}
/*
GLubyte *prepareImage(){
static GLubyte *imPtr = NULL;
//static int bufferSize;
//int readlines, linesize;
//GLubyte *ptr;
if(!imPtr) imPtr = calloc(100, sizeof(GLubyte));
return imPtr;
}
*/
int main(_U_ int argc, _U_ char** argv){
windowData *mainwin, _U_ *win, _U_ *third;
int w = 640, h = 480;
char *v[] = {PROJNAME, NULL};
int c = 1;
glutInit(&c, v);
initial_setup(); // locale & messages
XInitThreads(); // we need it for threaded windows
//BitmapBits = prepareImage();
mainwin = createGLwin("Sample window", w, h);
if(!mainwin) return 1;
pthread_create(&mainwin->thread, NULL, &change_image, (void*)mainwin);
win = createGLwin("Second window", w/2, h/2);
if(!win) return 1;
pthread_create(&win->thread, NULL, &change_image, (void*)win);
third = createGLwin("Second window", w/4, h/4);
if(!win) return 1;
pthread_create(&third->thread, NULL, &change_image, (void*)third);
// wait for end
glutMainLoop();
return 0;
}

6
image_view_module/main.h Normal file
View File

@ -0,0 +1,6 @@
// pthread_t thread, thread_m;
#include "events.h" // GLubyte etc
// GLubyte *prepareImage();
void help(char *s);