+++ /dev/null
-
-// Written and (C) by Francois Fleuret
-// Contact <francois.fleuret@idiap.ch> for comments & bug reports
-
-#include "retina.h"
-
-const int ring_width[] = { 128, 64, 32, 16, 8, 4, 1, 1, 1, 1};
-
-// const int ring_width[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-
-Retina::Retina(Universe *universe) : _universe(universe),
- _tag_map(new Tag *[_width * _height]),
- _tag_stack(new Tag[_width * _height]),
- _tag_stack_top(_tag_stack),
- _red_imap(new scalar_t[(_width + 1) * (_height + 1)]),
- _green_imap(new scalar_t[(_width + 1) * (_height + 1)]),
- _blue_imap(new scalar_t[(_width + 1) * (_height + 1)]) {
- reset();
-
- int np = 0;
- int w = _width;
- for(int k = 0; k < int(sizeof(ring_width)/sizeof(int)); k++) {
- np += 4 * (w / ring_width[k] - 1);
- w -= 2 * ring_width[k];
- }
-
- np *= 3;
- Map::init(np);
-}
-
-Retina::~Retina() {
- delete[] _tag_map;
- delete[] _tag_stack;
- delete[] _red_imap;
- delete[] _green_imap;
- delete[] _blue_imap;
-}
-
-void Retina::reset() {
- for(int k = 0; k < _width * _height; k++) _tag_map[k] = 0;
- _tag_stack_top = _tag_stack;
- _current_polygon = 0;
-}
-
-void Retina::draw_polygon(Polygon *p, scalar_t delta_x, scalar_t delta_y) {
- int nb = p->_nb_vertices;
-
- int ix[nb], iy[nb];
-
- for(int n = 0; n < nb; n++) {
- ix[n] = int(p->_x[n] + delta_x);
- iy[n] = int(p->_y[n] + delta_y);
- }
-
- scalar_t red = p->_red;
- scalar_t green = p->_green;
- scalar_t blue = p->_blue;
-
- int direction;
- if(iy[0] > iy[nb-1]) direction = 1;
- else if(iy[0] < iy[nb-1]) direction = -1;
- else direction = 0;
-
- for(int n = 0; n < nb; n++) {
- int m = (n+1)%nb;
-
- if(ix[n] >= 0 && ix[n] < _width && iy[n] >= 0 && iy[n] < _height &&
- ix[m] >= 0 && ix[m] < _width && iy[m] >= 0 && iy[m] < _height) {
-
- if(iy[m] > iy[n]) { // RIGHT BORDERS
-
- if(direction < 0) push_tag(1 + ix[n], iy[n], red, green, blue);
- for(int y = iy[n] + 1; y <= iy[m]; y++)
- push_tag(1 + ix[n] + ((ix[m] - ix[n]) * (y - iy[n]))/(iy[m] - iy[n]), y,
- red, green, blue);
- direction = 1;
-
- } else if(iy[m] < iy[n]) { // LEFT BORDERS
-
- if(direction >= 0) push_tag(ix[n], iy[n], red, green, blue);
- for(int y = iy[n] - 1; y >= iy[m]; y--)
- push_tag(ix[n] + ((ix[m] - ix[n]) * (y - iy[n]))/(iy[m] - iy[n]), y,
- red, green, blue);
- direction = -1;
-
- } else {
-
- if(direction >= 0) push_tag(ix[n]+1, iy[n], red, green, blue);
- push_tag(ix[m], iy[m], red, green, blue);
- direction = 0;
-
- }
-
- } else {
-
- if(iy[m] > iy[n]) { // RIGHT BORDERS
-
- if(direction < 0) protected_push_tag(1 + ix[n], iy[n], red, green, blue);
- for(int y = iy[n] + 1; y <= iy[m]; y++)
- protected_push_tag(1 + ix[n] + ((ix[m] - ix[n]) * (y - iy[n]))/(iy[m] - iy[n]), y,
- red, green, blue);
- direction = 1;
-
- } else if(iy[m] < iy[n]) { // LEFT BORDERS
-
- if(direction >= 0) protected_push_tag(ix[n], iy[n], red, green, blue);
- for(int y = iy[n] - 1; y >= iy[m]; y--)
- protected_push_tag(ix[n] + ((ix[m] - ix[n]) * (y - iy[n]))/(iy[m] - iy[n]), y,
- red, green, blue);
- direction = -1;
-
- } else {
-
- if(direction >= 0) protected_push_tag(ix[n]+1, iy[n], red, green, blue);
- protected_push_tag(ix[m], iy[m], red, green, blue);
- direction = 0;
-
- }
- }
- }
-
- _current_polygon++;
-}
-
-void Retina::fill() {
- bool in[_current_polygon];
- for(int p = 0; p < _current_polygon; p++) in[p] = false;
-
- scalar_t red[_current_polygon], green[_current_polygon], blue[_current_polygon];
- Tag **u = _tag_map;
-
- int lk = 0, k = 0;
-
- for(int x = 0; x < _width+1; x++) {
- _red_imap[k] = 0;
- _green_imap[k] = 0;
- _blue_imap[k] = 0;
- k++;
- }
-
- int current_index = -1;
- for(int y = 0; y < _height; y++) {
- scalar_t sred = 0, sgreen = 0, sblue = 0;
- _red_imap[k] = 0;
- _green_imap[k] = 0;
- _blue_imap[k] = 0;
- k++; lk++;
-
- for(int x = 0; x < _width; x++) {
- for(Tag *t = *u; t; t = t->next) {
- if(in[t->index]) {
- in[t->index] = false;
- if(t->index == current_index) {
- current_index--;
- while(current_index >= 0 && !in[current_index]) current_index--;
- }
- } else {
- in[t->index] = true;
- red[t->index] = t->red;
- green[t->index] = t->green;
- blue[t->index] = t->blue;
- if(t->index > current_index) current_index = t->index;
- }
- }
-
- if(current_index >= 0) {
- sred += red[current_index];
- sgreen += green[current_index];
- sblue += blue[current_index];
- }
-
- _red_imap[k] = sred + _red_imap[lk];
- _green_imap[k] = sgreen + _green_imap[lk];
- _blue_imap[k] = sblue + _blue_imap[lk];
-
- k++; lk++;
- u++;
- }
- }
-}
-
-void Retina::raw_rectangle(unsigned char *image, int xmin, int ymin, int w, int h,
- scalar_t red, scalar_t green, scalar_t blue) {
- for(int y = ymin; y < ymin + h; y++) for(int x = xmin; x < xmin + w; x++) {
- image[(y * _width + x) * 3 + 0] = (unsigned char) (255 * red);
- image[(y * _width + x) * 3 + 1] = (unsigned char) (255 * green);
- image[(y * _width + x) * 3 + 2] = (unsigned char) (255 * blue);
- }
-}
-
-void Retina::save_as_ppm(const char *filename) {
- unsigned char *image = new unsigned char[_width * _height * 3];
-
-
- int n = 0;
- int w = _width;
-
- for(int k = 0; k < int(sizeof(ring_width)/sizeof(int)); k++) {
- int s = ring_width[k];
- int z0 = (_width - w)/2;
- int z3 = z0 + w;
- int z2 = z3 - s;
-
- for(int x = z0; x < z2; x += s) {
- raw_rectangle(image, x, z0, s, s, parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- n += 3;
- raw_rectangle(image, z2, x, s, s, parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- n += 3;
- raw_rectangle(image, x + s, z2, s, s, parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- n += 3;
- raw_rectangle(image, z0, x + s, s, s, parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- n += 3;
- }
- w -= 2 * s;
- }
-
- ofstream out(filename);
- out << "P6" << endl;
- out << _width << " " << _height << endl;
- out << 255 << endl;
- out.write((char *) image, _width * _height * 3);
- out.flush();
- delete[] image;
-}
-
-void Retina::update_map() {
-
- reset();
- for(int p = 0; p < _universe->_nb_polygons; p++) if(_universe->_polygons[p])
- draw_polygon(_universe->_polygons[p], scalar_t(_width)/2 - _eye_x, scalar_t(_height)/2 - _eye_y);
- fill();
-
- int n = 0;
- int w = _width;
-
- for(int k = 0; k < int(sizeof(ring_width)/sizeof(int)); k++) {
-
- int s = ring_width[k];
- int z0 = (_width - w)/2;
- int z1 = z0 + s;
- int z3 = z0 + w;
- int z2 = z3 - s;
-
- for(int x = z0; x < z2; x += s) {
- parameters[n++] = red_sum(x, z0, x + s + 0, z1 + 0) / scalar_t(s * s);
- parameters[n++] = green_sum(x, z0, x + s + 0, z1 + 0) / scalar_t(s * s);
- parameters[n++] = blue_sum(x, z0, x + s + 0, z1 + 0) / scalar_t(s * s);
-
- parameters[n++] = red_sum(z2, x, z3 + 0, x + s + 0) / scalar_t(s * s);
- parameters[n++] = green_sum(z2, x, z3 + 0, x + s + 0) / scalar_t(s * s);
- parameters[n++] = blue_sum(z2, x, z3 + 0, x + s + 0) / scalar_t(s * s);
-
- parameters[n++] = red_sum(x + s, z2, x + 2 * s + 0, z3 + 0) / scalar_t(s * s);
- parameters[n++] = green_sum(x + s, z2, x + 2 * s + 0, z3 + 0) / scalar_t(s * s);
- parameters[n++] = blue_sum(x + s, z2, x + 2 * s + 0, z3 + 0) / scalar_t(s * s);
-
- parameters[n++] = red_sum(z0, x + s, z1 + 0, x + 2 * s + 0) / scalar_t(s * s);
- parameters[n++] = green_sum(z0, x + s, z1 + 0, x + 2 * s + 0) / scalar_t(s * s);
- parameters[n++] = blue_sum(z0, x + s, z1 + 0, x + 2 * s + 0) / scalar_t(s * s);
- }
- w -= 2 * s;
- }
-
-#ifdef DEBUG
- if(w != 0) {
- cerr << "Error in the retina ring sizes!" << endl;
- abort();
- }
-#endif
-
-}
-
-void Retina::draw_on_universe(SimpleWindow *window) {
- window->color(0.25, 0.25, 0.25);
- int xc = int(_eye_x), yc = int(_eye_y);
- window->draw_line(xc - _width/2, yc - _height/2, xc + _width/2, yc - _height/2);
- window->draw_line(xc + _width/2, yc - _height/2, xc + _width/2, yc + _height/2);
- window->draw_line(xc + _width/2, yc + _height/2, xc - _width/2, yc + _height/2);
- window->draw_line(xc - _width/2, yc + _height/2, xc - _width/2, yc - _height/2);
-}
-
-void Retina::draw_parameters(int x0, int y0, SimpleWindow *window) {
- int n = 0;
- int w = _width;
-
- for(int k = 0; k < int(sizeof(ring_width)/sizeof(int)); k++) {
- int s = ring_width[k];
- int z0 = (_width - w)/2;
- int z3 = z0 + w;
- int z2 = z3 - s;
-
- for(int x = z0; x < z2; x += s) {
- window->color(parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- window->fill_rectangle(x0 + x, y0 + z0, s, s);
- n += 3;
- window->color(parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- window->fill_rectangle(x0 + z2, y0 + x, s, s);
- n += 3;
- window->color(parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- window->fill_rectangle(x0 + x + s, y0 + z2, s, s);
- n += 3;
- window->color(parameters[n + 0], parameters[n + 1], parameters[n + 2]);
- window->fill_rectangle(x0 + z0, y0 + x + s, s, s);
- n += 3;
- }
- w -= 2 * s;
- }
-}
+++ /dev/null
-
-// Written and (C) by Francois Fleuret
-// Contact <francois.fleuret@idiap.ch> for comments & bug reports
-
-#ifndef RETINA_H
-#define RETINA_H
-
-#include <iostream>
-#include <fstream>
-
-using namespace std;
-
-#include "misc.h"
-#include "map.h"
-#include "universe.h"
-
-#include "simple_window.h"
-
-class Retina : public Map {
- static const int _width = 512, _height = 512;
-
- class Tag {
- public:
- int index;
- scalar_t red, green, blue;
- Tag *next;
- };
-
- Universe *_universe;
- Tag **_tag_map;
-
- // We have our own stack of tags to avoid numerous news and deletes
- Tag *_tag_stack, *_tag_stack_top;
- scalar_t *_red_imap, *_green_imap, *_blue_imap;
- int _current_polygon;
- scalar_t _eye_x, _eye_y;
-
- inline void protected_push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
- if(y >= 0 && y < _height) {
- if(x < 0) x = 0;
- else if(x >= _width) x = _width - 1;
- int t = y * _width + x;
- _tag_stack_top->next = _tag_map[t];
- _tag_stack_top->index = _current_polygon;
- _tag_stack_top->red = r;
- _tag_stack_top->green = g;
- _tag_stack_top->blue = b;
- _tag_map[t] = _tag_stack_top;
- _tag_stack_top++;
- }
- }
-
- inline void push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
- int t = y * _width + x;
- _tag_stack_top->next = _tag_map[t];
- _tag_stack_top->index = _current_polygon;
- _tag_stack_top->red = r;
- _tag_stack_top->green = g;
- _tag_stack_top->blue = b;
- _tag_map[t] = _tag_stack_top;
- _tag_stack_top++;
- }
-
- inline scalar_t red_sum(int xmin, int ymin, int xmax, int ymax) {
- return _red_imap[xmax + (_width + 1) * ymax]
- + _red_imap[xmin + (_width + 1) * ymin]
- - _red_imap[xmax + (_width + 1) * ymin]
- - _red_imap[xmin + (_width + 1) * ymax];
- }
-
- inline scalar_t green_sum(int xmin, int ymin, int xmax, int ymax) {
- return _green_imap[xmax + (_width + 1) * ymax]
- + _green_imap[xmin + (_width + 1) * ymin]
- - _green_imap[xmax + (_width + 1) * ymin]
- - _green_imap[xmin + (_width + 1) * ymax];
- }
-
- inline scalar_t blue_sum(int xmin, int ymin, int xmax, int ymax) {
- return _blue_imap[xmax + (_width + 1) * ymax]
- + _blue_imap[xmin + (_width + 1) * ymin]
- - _blue_imap[xmax + (_width + 1) * ymin]
- - _blue_imap[xmin + (_width + 1) * ymax];
- }
-
-public:
-
- inline int width() { return _width; }
- inline int height() { return _height; }
- inline void set_location(scalar_t x, scalar_t y) { _eye_x = x; _eye_y = y; }
-
- Retina(Universe *universe);
- ~Retina();
- void reset();
-
- void draw_polygon(Polygon *p, scalar_t delta_x, scalar_t delta_y);
- void fill();
-
- void raw_rectangle(unsigned char *image, int xmin, int ymin, int w, int h,
- scalar_t red, scalar_t green, scalar_t blue);
-
- void update_map();
- void draw_on_universe(SimpleWindow *window);
- void draw_parameters(int x0, int y0, SimpleWindow *window);
-
- void save_as_ppm(const char *filename);
-};
-
-#endif
+++ /dev/null
-
-////////////////////////////////////////////////////////////////////
-// START_IP_HEADER //
-// //
-// Written by Francois Fleuret //
-// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
-// //
-// END_IP_HEADER //
-////////////////////////////////////////////////////////////////////
-
- // ================================================
- // (3.1) Color Pseudo-objects (user-defined colors)
- // ================================================
- // This is used to define arbitrary colors beyond the 32 standard colors.
- // The color objects must be defined before any other Fig objects.
-
- // First line:
- // type name (brief description)
- // ---- ---- -------------------
- // int object_code (always 0)
- // int color_number (color number, from 32-543 (512 total))
- // hex string rgb values (hexadecimal string describing red,
-
-#include "xfig_tracer.h"
-
-XFigTracer::XFigTracer(const char *name) {
- _file = new ofstream(name);
- (*_file) << "#FIG 3.2" << endl;
- (*_file) << "Portrait" << endl;
- (*_file) << "Center" << endl;
- (*_file) << "Metric" << endl;
- (*_file) << "A4 " << endl;
- (*_file) << "100.00" << endl;
- (*_file) << "Single" << endl;
- (*_file) << "-2" << endl;
- (*_file) << "1200 2" << endl;
- _nb_user_colors = 0;
-}
-
-XFigTracer::~XFigTracer() {
- _file->flush();
- delete _file;
-}
-
-int XFigTracer::user_color(int red, int green, int blue) {
- for(int c = 0; c < _nb_user_colors; c++) {
- if(red == _palette_red[c] &&
- green == _palette_green[c] &&
- blue == _palette_blue[c]) return 32 + c;
- }
- cerr << "Unknown color!" << endl;
- exit(1);
-}
-
-void XFigTracer::add_color(int red, int green, int blue) {
- for(int c = 0; c < _nb_user_colors; c++) {
- if(red == _palette_red[c] &&
- green == _palette_green[c] &&
- blue == _palette_blue[c]) return;
- }
- if(_nb_user_colors < max_nb_user_colors) {
- _palette_red[_nb_user_colors] = red;
- _palette_green[_nb_user_colors] = green;
- _palette_blue[_nb_user_colors] = blue;
- char buffer[2];
- (*_file) << "0 " << 32 + _nb_user_colors << " #";
- sprintf(buffer, "%02x", _palette_red[_nb_user_colors]);
- (*_file) << buffer;
- sprintf(buffer, "%02x", _palette_green[_nb_user_colors]);
- (*_file) << buffer;
- sprintf(buffer, "%02x", _palette_blue[_nb_user_colors]);
- (*_file) << buffer;
- (*_file) << endl;
- _nb_user_colors++;
- } else {
- cerr << "Too many colors!" << endl;
- exit(1);
- }
-}
-
-void XFigTracer::draw_polygon(int red, int green, int blue,
- int nb_vertices, scalar_t *x, scalar_t *y) {
- int c = user_color(red, green, blue);
- (*_file) << "2 3 0 1 7 " << c << " 50 -1 20 0.000 0 0 -1 0 0 " << nb_vertices + 1 << endl;
- (*_file) << " ";
- for(int n = 0; n < nb_vertices; n++) (*_file) << " " << int(x[n]*10) << " " << int(y[n]*10);
- (*_file) << " " << int(x[0]*10) << " " << int(y[0]*10);
- (*_file) << endl;
-}