mirror of
https://github.com/SrIzan10/makesweet-api.git
synced 2026-05-01 10:55:14 +00:00
initial check-in
This commit is contained in:
6
.dockerignore
Normal file
6
.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
*~
|
||||
build
|
||||
stash
|
||||
old
|
||||
templates
|
||||
Dockerfile
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build
|
||||
12
CMakeLists.txt
Normal file
12
CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
PROJECT(makesweet)
|
||||
|
||||
SET(BUILD_SHARED_LIBS ON)
|
||||
|
||||
# Find YARP. Point the YARP_DIR environment variable at your build.
|
||||
FIND_PACKAGE(YARP)
|
||||
INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${YARP_LIBRARIES})
|
||||
|
||||
ADD_SUBDIRECTORY(src)
|
||||
35
Dockerfile
Normal file
35
Dockerfile
Normal file
@@ -0,0 +1,35 @@
|
||||
FROM ubuntu:14.04
|
||||
|
||||
RUN \
|
||||
apt-get update; \
|
||||
apt-get install -y build-essential
|
||||
|
||||
RUN \
|
||||
cd tmp; \
|
||||
apt-get update; \
|
||||
apt-get install -y cmake3 wget; \
|
||||
wget https://github.com/robotology/yarp/archive/v2.3.72.tar.gz; \
|
||||
tar xzvf v2.3.72.tar.gz; \
|
||||
mkdir yarp; \
|
||||
cd yarp; \
|
||||
cmake -DSKIP_ACE=TRUE ../yarp-*; \
|
||||
make
|
||||
|
||||
RUN \
|
||||
apt-get update; \
|
||||
apt-get install -y libgd2-noxpm-dev libzzip-dev
|
||||
|
||||
COPY . /makesweet/
|
||||
|
||||
RUN \
|
||||
cd /makesweet; \
|
||||
mkdir build; \
|
||||
cd build; \
|
||||
cmake -DYARP_DIR=/tmp/yarp ..; \
|
||||
make
|
||||
|
||||
RUN \
|
||||
echo "#!/bin/bash" > /reanimator; \
|
||||
echo "cd /share" >> /reanimator; \
|
||||
echo "/makesweet/build/bin/reanimator \"\$@\"" >> /reanimator; \
|
||||
chmod u+x /reanimator
|
||||
9
README.md
Normal file
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Putting pictures in animated templates.
|
||||
|
||||
```
|
||||
docker pull paulfitz/makesweet
|
||||
docker run -v $PWD:/share paulfitz/makesweet /reanimator \
|
||||
--zip templates/billboard-cityscape.zip \
|
||||
--in templates/frog.jpg \
|
||||
--gif animation.gif
|
||||
```
|
||||
15
src/CMakeLists.txt
Normal file
15
src/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
ADD_LIBRARY(msmap msmap.h msmap.c)
|
||||
ADD_LIBRARY(filer Filer.cpp Filer.h)
|
||||
TARGET_LINK_LIBRARIES(filer gd zzip)
|
||||
|
||||
ADD_EXECUTABLE(reanimator reanimator.cpp Prop.h Prop.cpp Pixer.h
|
||||
Mapping.h Repository.h Repository.cpp Render.h Render.cpp
|
||||
Input.h Input.cpp Inputs.h Renders.h Renders.cpp
|
||||
GifAnim.h GifAnim.cpp
|
||||
gd_topal.c)
|
||||
TARGET_LINK_LIBRARIES(reanimator filer)
|
||||
|
||||
7
src/Dbg.h
Normal file
7
src/Dbg.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef MS_DBG_INC
|
||||
#define MS_DBG_INC
|
||||
|
||||
extern int __ms_verbose;
|
||||
#define dbg_printf if (__ms_verbose) printf
|
||||
|
||||
#endif
|
||||
604
src/Filer.cpp
Normal file
604
src/Filer.cpp
Normal file
@@ -0,0 +1,604 @@
|
||||
#define USE_ZIP
|
||||
|
||||
#include "Filer.h"
|
||||
#include "Dbg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gd.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_ZIP
|
||||
#include <zzip/zzip.h>
|
||||
#endif
|
||||
|
||||
#define R gdTrueColorGetRed
|
||||
#define G gdTrueColorGetGreen
|
||||
#define B gdTrueColorGetBlue
|
||||
#define A gdTrueColorGetAlpha
|
||||
|
||||
using namespace std;
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::sig::file;
|
||||
using namespace yarp::sig::draw;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct dpIOCtx
|
||||
{
|
||||
gdIOCtx ctx;
|
||||
FILE *f;
|
||||
}
|
||||
fileIOCtx;
|
||||
|
||||
gdIOCtx *newFileCtx (FILE * f);
|
||||
|
||||
static int fileGetbuf (gdIOCtx *, void *, int);
|
||||
static int filePutbuf (gdIOCtx *, const void *, int);
|
||||
static void filePutchar (gdIOCtx *, int);
|
||||
static int fileGetchar (gdIOCtx * ctx);
|
||||
|
||||
static int fileSeek (struct gdIOCtx *, const int);
|
||||
static long fileTell (struct gdIOCtx *);
|
||||
static void gdFreeFileCtx (gdIOCtx * ctx);
|
||||
|
||||
|
||||
gdIOCtx *myNewFileCtx (FILE * f) {
|
||||
fileIOCtx *ctx;
|
||||
|
||||
ctx = (fileIOCtx *) new fileIOCtx;
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->f = f;
|
||||
|
||||
ctx->ctx.getC = fileGetchar;
|
||||
ctx->ctx.putC = filePutchar;
|
||||
|
||||
ctx->ctx.getBuf = fileGetbuf;
|
||||
ctx->ctx.putBuf = filePutbuf;
|
||||
|
||||
ctx->ctx.tell = fileTell;
|
||||
ctx->ctx.seek = fileSeek;
|
||||
|
||||
ctx->ctx.gd_free = gdFreeFileCtx;
|
||||
|
||||
return (gdIOCtx *) ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
gdFreeFileCtx (gdIOCtx * ctx)
|
||||
{
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
filePutbuf (gdIOCtx * ctx, const void *buf, int size)
|
||||
{
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
|
||||
return fwrite (buf, 1, size, fctx->f);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
fileGetbuf (gdIOCtx * ctx, void *buf, int size)
|
||||
{
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
|
||||
return (fread (buf, 1, size, fctx->f));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
filePutchar (gdIOCtx * ctx, int a)
|
||||
{
|
||||
unsigned char b;
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
|
||||
b = a;
|
||||
|
||||
putc (b, fctx->f);
|
||||
}
|
||||
|
||||
static int
|
||||
fileGetchar (gdIOCtx * ctx)
|
||||
{
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
|
||||
return getc (fctx->f);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fileSeek (struct gdIOCtx *ctx, const int pos)
|
||||
{
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
return (fseek (fctx->f, pos, SEEK_SET) == 0);
|
||||
}
|
||||
|
||||
static long
|
||||
fileTell (struct gdIOCtx *ctx)
|
||||
{
|
||||
fileIOCtx *fctx;
|
||||
fctx = (fileIOCtx *) ctx;
|
||||
|
||||
return ftell (fctx->f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef USE_ZIP
|
||||
|
||||
#include <zzip/zzip.h>
|
||||
|
||||
typedef struct dpZipIOCtx
|
||||
{
|
||||
gdIOCtx ctx;
|
||||
ZZIP_FILE *f;
|
||||
}
|
||||
zipIOCtx;
|
||||
|
||||
gdIOCtx *newZipCtx (ZZIP_FILE * f);
|
||||
|
||||
static int zipGetbuf (gdIOCtx *, void *, int);
|
||||
static int zipPutbuf (gdIOCtx *, const void *, int);
|
||||
static void zipPutchar (gdIOCtx *, int);
|
||||
static int zipGetchar (gdIOCtx * ctx);
|
||||
|
||||
static int zipSeek (struct gdIOCtx *, const int);
|
||||
static long zipTell (struct gdIOCtx *);
|
||||
static void gdFreeZipCtx (gdIOCtx * ctx);
|
||||
|
||||
|
||||
gdIOCtx *myNewZipCtx (ZZIP_FILE * f) {
|
||||
zipIOCtx *ctx;
|
||||
|
||||
ctx = (zipIOCtx *) new zipIOCtx;
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->f = f;
|
||||
|
||||
ctx->ctx.getC = zipGetchar;
|
||||
ctx->ctx.putC = zipPutchar;
|
||||
|
||||
ctx->ctx.getBuf = zipGetbuf;
|
||||
ctx->ctx.putBuf = zipPutbuf;
|
||||
|
||||
ctx->ctx.tell = zipTell;
|
||||
ctx->ctx.seek = zipSeek;
|
||||
|
||||
ctx->ctx.gd_free = gdFreeZipCtx;
|
||||
|
||||
return (gdIOCtx *) ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
gdFreeZipCtx (gdIOCtx * ctx)
|
||||
{
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
zipPutbuf (gdIOCtx * ctx, const void *buf, int size)
|
||||
{
|
||||
zipIOCtx *fctx;
|
||||
fctx = (zipIOCtx *) ctx;
|
||||
|
||||
fprintf(stderr,"CANNOT WRITE TO ZIP\n");
|
||||
exit(1);
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
zipGetbuf (gdIOCtx * ctx, void *buf, int size)
|
||||
{
|
||||
zipIOCtx *fctx;
|
||||
fctx = (zipIOCtx *) ctx;
|
||||
|
||||
return (zzip_fread (buf, 1, size, fctx->f));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
zipPutchar (gdIOCtx * ctx, int a)
|
||||
{
|
||||
fprintf(stderr,"CANNOT WRITE TO ZIP\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
zipGetchar (gdIOCtx * ctx)
|
||||
{
|
||||
zipIOCtx *fctx;
|
||||
fctx = (zipIOCtx *) ctx;
|
||||
|
||||
char buf;
|
||||
int r = (zzip_fread (&buf, 1, 1, fctx->f));
|
||||
if (r<0) return -1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
zipSeek (struct gdIOCtx *ctx, const int pos)
|
||||
{
|
||||
zipIOCtx *fctx;
|
||||
fctx = (zipIOCtx *) ctx;
|
||||
return (zzip_seek (fctx->f, pos, SEEK_SET) == 0);
|
||||
}
|
||||
|
||||
static long
|
||||
zipTell (struct gdIOCtx *ctx)
|
||||
{
|
||||
zipIOCtx *fctx;
|
||||
fctx = (zipIOCtx *) ctx;
|
||||
|
||||
return zzip_tell (fctx->f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static const char * ispng(const char * name, int & result) {
|
||||
FILE * png = fopen(name, "rb");
|
||||
char buf[32];
|
||||
if (!png) {
|
||||
return "ispng: Failure in fopen";
|
||||
}
|
||||
if (8 != fread(buf, 1, 8, png)) {
|
||||
fclose(png);
|
||||
return "ispng: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "\x89PNG\x0D\x0A\x1A\x0A", 8);
|
||||
fclose(png);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * isgif(const char * name, int & result) {
|
||||
FILE * gif = fopen(name, "rb");
|
||||
char buf[32];
|
||||
if (!gif) {
|
||||
return "isgif: Failure in fopen";
|
||||
}
|
||||
if (6 != fread(buf, 1, 6, gif)) {
|
||||
fclose(gif);
|
||||
return "isgif: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "GIF89a", 6);
|
||||
fclose(gif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * isjpg(const char * name, int & result) {
|
||||
FILE * jpg = fopen(name, "rb");
|
||||
char buf[32];
|
||||
if (!jpg) {
|
||||
return "isjpg: Failure in fopen";
|
||||
}
|
||||
if (2 != fread(buf, 1, 2, jpg)) {
|
||||
fclose(jpg);
|
||||
return "isjpg: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "\xFF\xD8", 2);
|
||||
fclose(jpg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static const char * ispng(gdIOCtx * ctx, int & result) {
|
||||
char buf[32];
|
||||
ctx->seek(ctx,0);
|
||||
if (8 != ctx->getBuf(ctx, buf, 8)) {
|
||||
return "ispng: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "\x89PNG\x0D\x0A\x1A\x0A", 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * isgif(gdIOCtx * ctx, int & result) {
|
||||
char buf[32];
|
||||
ctx->seek(ctx,0);
|
||||
if (6 != ctx->getBuf(ctx, buf, 6)) {
|
||||
return "isgif: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "GIF89a", 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * isjpg(gdIOCtx * ctx, int & result) {
|
||||
char buf[32];
|
||||
ctx->seek(ctx,0);
|
||||
if (2 != ctx->getBuf(ctx, buf, 2)) {
|
||||
return "isjpg: couldn't read magic number";
|
||||
}
|
||||
result = !memcmp(buf, "\xFF\xD8", 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string Filer::load_text(const char *fname) {
|
||||
gdImagePtr img = NULL;
|
||||
gdIOCtx *ctx = NULL;
|
||||
|
||||
FILE *fd = NULL;
|
||||
|
||||
#ifdef USE_ZIP
|
||||
ZZIP_DIR *zip = (ZZIP_DIR *)src_zip;
|
||||
|
||||
ZZIP_FILE *zd = NULL;
|
||||
if (zip) {
|
||||
zd = zzip_file_open(zip,fname,ZZIP_CASELESS);
|
||||
if (!zd) {
|
||||
dbg_printf("Cannot open %s in zip\n", fname);
|
||||
return "";
|
||||
} else {
|
||||
dbg_printf("Got %s from zip\n", fname);
|
||||
}
|
||||
ctx = myNewZipCtx(zd);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ctx) {
|
||||
fd = fopen(fname,"r");
|
||||
if (fd==NULL) {
|
||||
fprintf(stderr,"Cannot open %s\n", fname);
|
||||
return "";
|
||||
}
|
||||
ctx = myNewFileCtx(fd);
|
||||
}
|
||||
|
||||
std::string result;
|
||||
if (ctx) {
|
||||
ctx->seek(ctx,0);
|
||||
|
||||
char buf[1024];
|
||||
int r = 0;
|
||||
do {
|
||||
r = ctx->getBuf(ctx,buf,sizeof(buf));
|
||||
if (r>0) {
|
||||
result.append(buf,r);
|
||||
}
|
||||
} while (r>0);
|
||||
ctx->gd_free(ctx);
|
||||
}
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
}
|
||||
#ifdef USE_ZIP
|
||||
if (zd) {
|
||||
zzip_file_close(zd);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
static gdImagePtr gd_load(const char *fname, void *src_zip) {
|
||||
gdImagePtr img = NULL;
|
||||
gdIOCtx *ctx = NULL;
|
||||
|
||||
FILE *fd = NULL;
|
||||
|
||||
#ifdef USE_ZIP
|
||||
ZZIP_DIR *zip = (ZZIP_DIR *)src_zip;
|
||||
ZZIP_FILE *zd = NULL;
|
||||
if (zip) {
|
||||
zd = zzip_file_open(zip,fname,ZZIP_CASELESS);
|
||||
if (!zd) {
|
||||
fprintf(stderr,"Cannot open %s in zip\n", fname);
|
||||
exit(1);
|
||||
} else {
|
||||
dbg_printf("Got %s from zip\n", fname);
|
||||
}
|
||||
ctx = myNewZipCtx(zd);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ctx) {
|
||||
fd = fopen(fname,"r");
|
||||
if (fd==NULL) {
|
||||
fprintf(stderr,"Cannot open %s\n", fname);
|
||||
return NULL;
|
||||
}
|
||||
ctx = myNewFileCtx(fd);
|
||||
}
|
||||
|
||||
if (ctx) {
|
||||
|
||||
int png = 0;
|
||||
int jpg = 0;
|
||||
int gif = 0;
|
||||
ispng(ctx,png);
|
||||
if (!png) {
|
||||
isjpg(ctx,jpg);
|
||||
if (!jpg) {
|
||||
isgif(ctx,gif);
|
||||
}
|
||||
}
|
||||
if (!(png||jpg||gif)) {
|
||||
fprintf(stderr,"Cannot process %s\n", fname);
|
||||
return NULL;
|
||||
}
|
||||
ctx->seek(ctx,0);
|
||||
|
||||
if (png) {
|
||||
img = gdImageCreateFromPngCtx(ctx);
|
||||
} else if (jpg) {
|
||||
img = gdImageCreateFromJpegCtx(ctx);
|
||||
} else if (gif) {
|
||||
img = gdImageCreateFromGifCtx(ctx);
|
||||
}
|
||||
ctx->gd_free(ctx);
|
||||
}
|
||||
bool found = false;
|
||||
if (img!=NULL) {
|
||||
found = true;
|
||||
gdImageSaveAlpha(img, 1);
|
||||
gdImageAlphaBlending(img, 0);
|
||||
}
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
}
|
||||
#ifdef USE_ZIP
|
||||
if (zd) {
|
||||
zzip_file_close(zd);
|
||||
}
|
||||
#endif
|
||||
if (img) {
|
||||
dbg_printf(" loaded image of size %dx%d\n", img->sx, img->sy);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
static bool yarp_load(const char *fname,
|
||||
yarp::sig::ImageOf<T>& src, void *src_zip) {
|
||||
|
||||
bool found = false;
|
||||
gdImagePtr img = gd_load(fname,src_zip);
|
||||
|
||||
if (img!=NULL) {
|
||||
found = true;
|
||||
src.resize(img->sx,img->sy);
|
||||
IMGFOR(src,x,y) {
|
||||
int pi = gdImageGetPixel(img,x,y);
|
||||
int r = R(pi);
|
||||
int g = G(pi);
|
||||
int b = B(pi);
|
||||
int a = A(pi);
|
||||
a *= 2;
|
||||
if (a>253) a = 255;
|
||||
src(x,y) = T(r,g,b,255-a);
|
||||
}
|
||||
gdFree(img);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool Filer::load(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelRgba>& src) {
|
||||
return yarp_load(fname,src,src_zip);
|
||||
}
|
||||
|
||||
bool Filer::load(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra>& src) {
|
||||
return yarp_load(fname,src,src_zip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
static bool yarp_save(const char *fname,
|
||||
yarp::sig::ImageOf<T>& src) {
|
||||
|
||||
string n = fname;
|
||||
bool is_png = false;
|
||||
bool is_jpg = false;
|
||||
|
||||
if (n.rfind(".png")==n.length()-4) {
|
||||
is_png = true;
|
||||
}
|
||||
if (n.rfind(".jpg")==n.length()-4) {
|
||||
is_jpg = true;
|
||||
}
|
||||
gdImageStruct access;
|
||||
ImageOf<PixelBgra> idest;
|
||||
gdImagePtr im2;
|
||||
im2 = gdImageCreateTrueColor(src.width(),src.height());
|
||||
access = *im2;
|
||||
gdImageDestroy(im2);
|
||||
|
||||
gdImageSaveAlpha(&access, 1);
|
||||
gdImageAlphaBlending(&access, 0);
|
||||
|
||||
idest.copy(src);
|
||||
IMGFOR(idest,x,y) {
|
||||
PixelBgra& pix = idest(x,y);
|
||||
pix.a = 255-pix.a;
|
||||
pix.a /= 2;
|
||||
}
|
||||
access.tpixels = (int**)idest.getRowArray();
|
||||
access.sx = idest.width();
|
||||
access.sy = idest.height();
|
||||
|
||||
FILE *test = fopen(fname,"wb");
|
||||
if (is_png) {
|
||||
gdImagePng(&access,test);
|
||||
} else if (is_jpg) {
|
||||
gdImageJpeg(&access,test,95);
|
||||
} else {
|
||||
fprintf(stderr,"unknown image format\n");
|
||||
exit(1);
|
||||
}
|
||||
fclose(test);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Filer::save(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelRgba>& src) {
|
||||
return yarp_save(fname,src);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Filer::save(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra>& src) {
|
||||
return yarp_save(fname,src);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Filer::load_zip(const char *fname) {
|
||||
#ifdef USE_ZIP
|
||||
dbg_printf("Loading zip %s\n", fname);
|
||||
src_zip = zzip_opendir(fname);
|
||||
if (!src_zip) {
|
||||
fprintf(stderr, "failed to load zip %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Filer::unload_zip() {
|
||||
#ifdef USE_ZIP
|
||||
ZZIP_DIR *zip = (ZZIP_DIR *)src_zip;
|
||||
if (zip) {
|
||||
zzip_closedir(zip);
|
||||
src_zip = NULL;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
41
src/Filer.h
Normal file
41
src/Filer.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef FILER_INC
|
||||
#define FILER_INC
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <yarp/sig/all.h>
|
||||
|
||||
class Filer {
|
||||
private:
|
||||
void *src_zip;
|
||||
public:
|
||||
Filer() {
|
||||
src_zip = NULL;
|
||||
}
|
||||
|
||||
~Filer() {
|
||||
if (src_zip) unload_zip();
|
||||
}
|
||||
|
||||
bool load_zip(const char *fname);
|
||||
bool unload_zip();
|
||||
|
||||
bool load(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelRgba>& src);
|
||||
|
||||
bool save(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelRgba>& src);
|
||||
|
||||
|
||||
// GD compatible, apart from alpha channel
|
||||
bool load(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra>& src);
|
||||
|
||||
bool save(const char *fname,
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra>& src);
|
||||
|
||||
std::string load_text(const char *fname);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
236
src/GifAnim.cpp
Normal file
236
src/GifAnim.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
#include "GifAnim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gd.h>
|
||||
#include "gd_mod.h"
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::os;
|
||||
|
||||
#include "Dbg.h"
|
||||
|
||||
static int raw_dither[16][16] = { {0, 192, 48, 240, 12, 204, 60, 252, 3, 195, 51, 243, 15, 207, 63, 255}, {128, 64, 176, 112, 140, 76, 188, 124, 131, 67, 179, 115, 143, 79, 191, 127}, {32, 224, 16, 208, 44, 236, 28, 220, 35, 227, 19, 211, 47, 239, 31, 223}, {160, 96, 144, 80, 172, 108, 156, 92, 163, 99, 147, 83, 175, 111, 159, 95}, {8, 200, 56, 248, 4, 196, 52, 244, 11, 203, 59, 251, 7, 199, 55, 247}, {136, 72, 184, 120, 132, 68, 180, 116, 139, 75, 187, 123, 135, 71, 183, 119}, {40, 232, 24, 216, 36, 228, 20, 212, 43, 235, 27, 219, 39, 231, 23, 215}, {168, 104, 152, 88, 164, 100, 148, 84, 171, 107, 155, 91, 167, 103, 151, 87}, {2, 194, 50, 242, 14, 206, 62, 254, 1, 193, 49, 241, 13, 205, 61, 253}, {130, 66, 178, 114, 142, 78, 190, 126, 129, 65, 177, 113, 141, 77, 189, 125}, {34, 226, 18, 210, 46, 238, 30, 222, 33, 225, 17, 209, 45, 237, 29, 221}, {162, 98, 146, 82, 174, 110, 158, 94, 161, 97, 145, 81, 173, 109, 157, 93}, {10, 202, 58, 250, 6, 198, 54, 246, 9, 201, 57, 249, 5, 197, 53, 245}, {138, 74, 186, 122, 134, 70, 182, 118, 137, 73, 185, 121, 133, 69, 181, 117}, {42, 234, 26, 218, 38, 230, 22, 214, 41, 233, 25, 217, 37, 229, 21, 213}, {170, 106, 154, 90, 166, 102, 150, 86, 169, 105, 153, 89, 165, 101, 149, 85} };
|
||||
|
||||
static int raw_dither_dim = 16;
|
||||
|
||||
GifAnim::~GifAnim() {
|
||||
for (int i=0; i<(int)blocks.size(); i++) {
|
||||
gdFree(blocks[i].get());
|
||||
}
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
void GifAnim::check() {
|
||||
if (!renders) {
|
||||
fprintf(stderr,"No renders for GifAnim!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void sync_palette(gdImagePtr from, gdImagePtr to) {
|
||||
for (int i = 0; i<gdMaxColors; i++) {
|
||||
to->red[i] = from->red[i];
|
||||
to->blue[i] = from->blue[i];
|
||||
to->green[i] = from->green[i];
|
||||
to->alpha[i] = from->alpha[i];
|
||||
to->open[i] = from->open[i];
|
||||
}
|
||||
to->colorsTotal = from->colorsTotal;
|
||||
}
|
||||
|
||||
inline int crop(int x) {
|
||||
if (x>255) return 255;
|
||||
return x;
|
||||
}
|
||||
|
||||
void GifAnim::apply() {
|
||||
bool local_color = false;
|
||||
int loops = 0;
|
||||
bool have_prev = false;
|
||||
bool dither = true;
|
||||
|
||||
int step = int(period*100+0.5);
|
||||
int last_step = int(hold*100+0.5);
|
||||
dbg_printf("Step is %d (from %g)\n", step, period);
|
||||
|
||||
check();
|
||||
int pals = (int)palette_frames.size();
|
||||
int pal_index = -1;
|
||||
if (pals<1) {
|
||||
fprintf(stderr,"No palette frames\n");
|
||||
exit(1);
|
||||
}
|
||||
ImageOf<PixelBgra> pal_image;
|
||||
ImageOf<PixelBgra> *p_pal_image = &pal_image;
|
||||
for (int i=0; i<pals; i++) {
|
||||
int idx = palette_frames[i];
|
||||
Render *r = renders->get_render(idx);
|
||||
renders->remove_mapping(idx);
|
||||
if (pals==1) {
|
||||
p_pal_image = &r->get_mod();
|
||||
pal_index = idx;
|
||||
} else {
|
||||
const ImageOf<PixelBgra>& img = r->get();
|
||||
pal_image.resize(img);
|
||||
int w = pal_image.width();
|
||||
int h = pal_image.height();
|
||||
for (int k=i; k<w*h; k+=pals) {
|
||||
int xx = k%w;
|
||||
int yy = k/w;
|
||||
pal_image(xx,yy) = img(xx,yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ww = p_pal_image->width();
|
||||
int hh = p_pal_image->height();
|
||||
|
||||
gdImageStruct gd_wrap;
|
||||
gdImagePtr im_tmp;
|
||||
im_tmp = gdImageCreateTrueColor(ww,hh);
|
||||
gd_wrap = *im_tmp;
|
||||
gdImageDestroy(im_tmp);
|
||||
gdImageSaveAlpha(&gd_wrap, 1);
|
||||
gdImageAlphaBlending(&gd_wrap, 0);
|
||||
|
||||
gdImagePtr gd_palette = gdImageCreate(ww,hh);
|
||||
gd_wrap.tpixels = (int**)p_pal_image->getRowArray();
|
||||
|
||||
double tot = 0;
|
||||
IMGFOR(*p_pal_image,ww,hh) {
|
||||
PixelBgra pix = p_pal_image->pixel(ww,hh);
|
||||
tot += pix.r;
|
||||
}
|
||||
|
||||
void *quantizer = pf_gdQuantizeInit(&gd_wrap,gd_palette);
|
||||
pf_gdQuantizeApply(quantizer,&gd_wrap,1,gd_palette);
|
||||
|
||||
gdImagePtr gd_prev = gdImageCreate(ww,hh);
|
||||
gdImagePtr gd_curr = gdImageCreate(ww,hh);
|
||||
gdImagePtr gd_pre_prev = gdImageCreate(ww,hh);
|
||||
|
||||
sync_palette(gd_palette,gd_prev);
|
||||
sync_palette(gd_palette,gd_curr);
|
||||
sync_palette(gd_palette,gd_pre_prev);
|
||||
|
||||
int frames = renders->length();
|
||||
|
||||
int sz = 0;
|
||||
void *mem = gdImageGifAnimBeginPtr(gd_palette,&sz,
|
||||
1,
|
||||
loops);
|
||||
blocks.push_back(Bytes((char*)mem,(size_t)sz));
|
||||
|
||||
int accum_delay = 0;
|
||||
// bool have_r = false;
|
||||
//Render *r_prev = NULL;
|
||||
//Render *r_pre_prev = NULL;
|
||||
int emit_ct = 0;
|
||||
int step_pending = 0;
|
||||
for (int i=0; i<frames; i++) {
|
||||
step_pending += step;
|
||||
dbg_printf("Working on frame %d\n", i);
|
||||
|
||||
if (i!=pal_index) {
|
||||
Render *r = renders->get_render(i);
|
||||
renders->remove_mapping(i);
|
||||
ImageOf<PixelBgra>& img = r->get_mod();
|
||||
gd_wrap.tpixels = (int**)img.getRowArray();
|
||||
pf_gdQuantizeApply(quantizer,&gd_wrap,1,gd_curr);
|
||||
} else {
|
||||
dbg_printf("Substitute in palette frame\n");
|
||||
gdImagePtr tmp = gd_palette;
|
||||
gd_palette = gd_curr;
|
||||
gd_curr = tmp;
|
||||
}
|
||||
renders->remove_render(i);
|
||||
|
||||
bool change = false;
|
||||
if (i>0) {
|
||||
for (int x=0; x<ww && !change; x++) {
|
||||
for (int y=0; y<hh; y++) {
|
||||
int p0 = gd_prev->pixels[y][x];
|
||||
int p1 = gd_curr->pixels[y][x];
|
||||
if (p0!=p1) {
|
||||
change = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (change) {
|
||||
mem = gdImageGifAnimAddPtr(gd_prev,&sz,
|
||||
local_color?1:0,
|
||||
0,0,
|
||||
step_pending,1,
|
||||
(emit_ct>=1)?gd_pre_prev:NULL);
|
||||
dbg_printf(" Generated frame, %d ticks\n", step_pending);
|
||||
step_pending = 0;
|
||||
emit_ct++;
|
||||
blocks.push_back(Bytes((char*)mem,(size_t)sz));
|
||||
}
|
||||
|
||||
if (change) {
|
||||
//r_pre_prev = r_prev;
|
||||
gdImagePtr tmp = gd_pre_prev;
|
||||
gd_pre_prev = gd_prev;
|
||||
gd_prev = gd_curr;
|
||||
gd_curr = tmp;
|
||||
} else {
|
||||
gdImagePtr tmp = gd_prev;
|
||||
gd_prev = gd_curr;
|
||||
gd_curr = tmp;
|
||||
}
|
||||
//r_prev = r;
|
||||
|
||||
// ...
|
||||
//renders->remove_render(i);
|
||||
//renders->remove_mapping(i);
|
||||
}
|
||||
|
||||
step_pending += step;
|
||||
step_pending += last_step;
|
||||
if (frames) {
|
||||
mem = gdImageGifAnimAddPtr(gd_prev,&sz,
|
||||
local_color?1:0,
|
||||
0,0,
|
||||
step_pending,1,
|
||||
(emit_ct>=1)?gd_pre_prev:NULL);
|
||||
emit_ct++;
|
||||
blocks.push_back(Bytes((char*)mem,(size_t)sz));
|
||||
dbg_printf(" Generated final frame, %d ticks\n",
|
||||
step_pending);
|
||||
}
|
||||
|
||||
pf_gdQuantizeFini(quantizer);
|
||||
quantizer = NULL;
|
||||
|
||||
gdImageDestroy(gd_curr);
|
||||
gdImageDestroy(gd_prev);
|
||||
gdImageDestroy(gd_pre_prev);
|
||||
gdImageDestroy(gd_palette);
|
||||
|
||||
mem = gdImageGifAnimEndPtr(&sz);
|
||||
blocks.push_back(Bytes((char*)mem,(size_t)sz));
|
||||
}
|
||||
|
||||
|
||||
void GifAnim::save(const char *fname) {
|
||||
FILE *fout = fopen(fname,"wb");
|
||||
if (!fout) {
|
||||
fprintf(stderr,"Cannot write GIF\n");
|
||||
exit(1);
|
||||
}
|
||||
for (int i=0; i<(int)blocks.size(); i++) {
|
||||
Bytes& b = blocks[i];
|
||||
fwrite(b.get(),1,b.length(),fout);
|
||||
}
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
|
||||
55
src/GifAnim.h
Normal file
55
src/GifAnim.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef GIFANIM_INC
|
||||
#define GIFANIM_INC
|
||||
|
||||
#include "Renders.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <yarp/os/Bytes.h>
|
||||
|
||||
class GifAnim {
|
||||
private:
|
||||
Renders *renders;
|
||||
std::vector<int> palette_frames;
|
||||
std::vector<yarp::os::Bytes> blocks;
|
||||
double period;
|
||||
double hold;
|
||||
bool early_release;
|
||||
|
||||
public:
|
||||
|
||||
GifAnim() {
|
||||
renders = 0 /*NULL*/;
|
||||
period = 0.1;
|
||||
hold = 5;
|
||||
early_release = true;
|
||||
}
|
||||
|
||||
~GifAnim();
|
||||
|
||||
void attach_renders(Renders *renders) {
|
||||
this->renders = renders;
|
||||
}
|
||||
|
||||
void check();
|
||||
|
||||
void set_palette(int index) {
|
||||
palette_frames.clear();
|
||||
palette_frames.push_back(index);
|
||||
}
|
||||
|
||||
void set_palette(const std::vector<int>& palette) {
|
||||
palette_frames = palette;
|
||||
}
|
||||
|
||||
void apply();
|
||||
|
||||
void save(const char *fname);
|
||||
|
||||
void set_timing(double period, double hold) {
|
||||
this->period = period;
|
||||
this->hold = hold;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
30
src/Input.cpp
Normal file
30
src/Input.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "Input.h"
|
||||
#include "Dbg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace yarp::os;
|
||||
|
||||
bool Input::load(const char *fname) {
|
||||
Filer filer;
|
||||
dbg_printf("Loading %s\n", fname);
|
||||
if (!filer.load(fname,src)) {
|
||||
fprintf(stderr, "Failed to load %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
src.safePixel(-1,-1).a = 0;
|
||||
in_scale = src.width();
|
||||
in_x0 = 0;
|
||||
in_y0 = 0;
|
||||
if (src.height()>src.width()) {
|
||||
in_scale = src.height();
|
||||
in_x0 = -(-src.width()+src.height())/2;
|
||||
} else {
|
||||
in_y0 = -(src.width()-src.height())/2;
|
||||
}
|
||||
xa = cos(theta);
|
||||
ya = sin(theta);
|
||||
return true;
|
||||
}
|
||||
50
src/Input.h
Normal file
50
src/Input.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef INPUT_INC
|
||||
#define INPUT_INC
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
|
||||
#include "Filer.h"
|
||||
|
||||
class Input {
|
||||
private:
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra> src;
|
||||
double theta;
|
||||
|
||||
public:
|
||||
|
||||
const yarp::sig::ImageOf<yarp::sig::PixelBgra>& get() const { return src; }
|
||||
|
||||
// scale, angle, and offset in source coordinates
|
||||
double xs;
|
||||
double ys;
|
||||
double xo;
|
||||
double yo;
|
||||
|
||||
int layer;
|
||||
|
||||
int in_scale;
|
||||
double in_x0;
|
||||
double in_y0;
|
||||
|
||||
double xa;
|
||||
double ya;
|
||||
|
||||
Input() {
|
||||
xs = ys = 1;
|
||||
theta = 0;
|
||||
xo = yo = 0;
|
||||
layer = 1;
|
||||
in_scale = 0;
|
||||
in_x0 = in_y0 = 0;
|
||||
xa = 1;
|
||||
ya = 0;
|
||||
}
|
||||
|
||||
bool load(const char *fname);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
27
src/Inputs.h
Normal file
27
src/Inputs.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef INPUTS_INC
|
||||
#define INPUTS_INC
|
||||
|
||||
#include "Input.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Inputs {
|
||||
private:
|
||||
std::vector<Input> data;
|
||||
public:
|
||||
|
||||
Input& add() {
|
||||
data.push_back(Input());
|
||||
return data.back();
|
||||
}
|
||||
|
||||
const std::vector<Input>& get() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<Input>& get_mod() {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
20
src/Mapping.h
Normal file
20
src/Mapping.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef MAPPING_INC
|
||||
#define MAPPING_INC
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
#include <string>
|
||||
|
||||
class Mapping {
|
||||
public:
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra> map1, map2, light, dark, neutral;
|
||||
std::string map1_name, map2_name, light_name, dark_name, neutral_name;
|
||||
|
||||
// scale factor for interpreting map
|
||||
int scale;
|
||||
|
||||
Mapping() {
|
||||
scale = 1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
59
src/Pixer.h
Normal file
59
src/Pixer.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef PIXER_INC
|
||||
#define PIXER_INC
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
|
||||
class Pixer {
|
||||
public:
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
double a;
|
||||
|
||||
Pixer operator+(const Pixer& alt) {
|
||||
Pixer p;
|
||||
p.r = r+alt.r;
|
||||
p.g = g+alt.g;
|
||||
p.b = b+alt.b;
|
||||
p.a = a+alt.a;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator+=(const yarp::sig::PixelBgra& pix) {
|
||||
r += pix.r;
|
||||
g += pix.g;
|
||||
b += pix.b;
|
||||
a += pix.a;
|
||||
}
|
||||
|
||||
Pixer operator*(double v) {
|
||||
Pixer p;
|
||||
p.r = r*v;
|
||||
p.g = g*v;
|
||||
p.b = b*v;
|
||||
p.a = a*v;
|
||||
return p;
|
||||
}
|
||||
|
||||
Pixer operator/(double v) {
|
||||
Pixer p;
|
||||
p.r = r/v;
|
||||
p.g = g/v;
|
||||
p.b = b/v;
|
||||
p.a = a/v;
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
inline Pixer sampleLinear(const yarp::sig::ImageOf<yarp::sig::PixelBgra>& src,
|
||||
double x, double y) {
|
||||
const yarp::sig::PixelBgra& p = src.safePixel(x,y);
|
||||
Pixer v;
|
||||
v.r = p.r;
|
||||
v.g = p.g;
|
||||
v.b = p.b;
|
||||
v.a = p.a;
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif
|
||||
82
src/Prop.cpp
Normal file
82
src/Prop.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "Prop.h"
|
||||
|
||||
using namespace yarp::os;
|
||||
using namespace std;
|
||||
|
||||
void Prop::scan_hx(const std::string& txt, yarp::os::Property& data) {
|
||||
data.clear();
|
||||
string line;
|
||||
for (int i=0; i<(int)txt.size(); i++) {
|
||||
char ch = txt[i];
|
||||
if (ch=='\r'||ch=='\n') {
|
||||
line = "";
|
||||
continue;
|
||||
}
|
||||
if (ch=='[') {
|
||||
line += '(';
|
||||
continue;
|
||||
}
|
||||
if (ch==']') {
|
||||
line += ')';
|
||||
continue;
|
||||
}
|
||||
if (ch==',') {
|
||||
line += ' ';
|
||||
continue;
|
||||
}
|
||||
if (ch!=';') {
|
||||
line += ch;
|
||||
continue;
|
||||
}
|
||||
Bottle b(line.c_str());
|
||||
|
||||
string var = "dud";
|
||||
for (int j=1; j<b.size(); j++) {
|
||||
if (b.get(j-1).asString()=="var") {
|
||||
var = b.get(j).asString();
|
||||
continue;
|
||||
}
|
||||
if (b.get(j-1).asString()=="=") {
|
||||
Value v = b.get(j);
|
||||
ConstString s = v.asString();
|
||||
if (s=="true") {
|
||||
data.put(var.c_str(),1);
|
||||
} else if (s=="false") {
|
||||
data.put(var.c_str(),0);
|
||||
} else {
|
||||
data.put(var.c_str(),v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Prop::scan_xml(const std::string& txt, yarp::os::Property& data) {
|
||||
data.clear();
|
||||
string line;
|
||||
for (int i=0; i<(int)txt.size(); i++) {
|
||||
char ch = txt[i];
|
||||
if (ch=='\"') {
|
||||
line += " ";
|
||||
continue;
|
||||
}
|
||||
if (ch!='\r'&&ch!='\n') {
|
||||
line += ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
Bottle b(line.c_str());
|
||||
|
||||
string var = "dud";
|
||||
for (int j=1; j<b.size(); j++) {
|
||||
if (b.get(j-1).asString()=="id=") {
|
||||
var = b.get(j).asString();
|
||||
continue;
|
||||
}
|
||||
if (b.get(j-1).asString()=="import=") {
|
||||
data.put(var.c_str(),b.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/Prop.h
Normal file
14
src/Prop.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef PROP_INC
|
||||
#define PROP_INC
|
||||
|
||||
#include <string>
|
||||
#include <yarp/os/Property.h>
|
||||
|
||||
class Prop {
|
||||
public:
|
||||
static void scan_hx(const std::string& txt, yarp::os::Property& data);
|
||||
|
||||
static void scan_xml(const std::string& txt, yarp::os::Property& data);
|
||||
};
|
||||
|
||||
#endif
|
||||
463
src/Render.cpp
Normal file
463
src/Render.cpp
Normal file
@@ -0,0 +1,463 @@
|
||||
#include "Render.h"
|
||||
#include "Pixer.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gd.h>
|
||||
|
||||
#include "Dbg.h"
|
||||
|
||||
#include <yarp/sig/ImageFile.h>
|
||||
using namespace yarp::sig::file;
|
||||
|
||||
using namespace yarp::sig;
|
||||
|
||||
#define RR (4096/2)
|
||||
|
||||
static int render_count = 0;
|
||||
|
||||
static double distance(double x1, double y1,
|
||||
double x2, double y2) {
|
||||
return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
|
||||
}
|
||||
|
||||
int Render::render_count() {
|
||||
return ::render_count;
|
||||
}
|
||||
|
||||
void Render::check() {
|
||||
if (!mapping) {
|
||||
fprintf(stderr,"No mapping!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void Render::add(const Input& in) {
|
||||
check();
|
||||
double active_scale = in.in_scale;
|
||||
active_scale /= 2; //mapping->scale;
|
||||
|
||||
int w = mapping->light.width();
|
||||
int h = mapping->light.height();
|
||||
|
||||
if (mapping->map1.width()<w) {
|
||||
return;
|
||||
}
|
||||
|
||||
int off = (mapping->map2.height()-mapping->light.height())/2;
|
||||
|
||||
if (mapping->map1.width()!=mapping->neutral.width()) return;
|
||||
if (mapping->map2.width()!=mapping->neutral.width()) return;
|
||||
|
||||
IMGFOR(out,x,y) {
|
||||
PixelBgra& pix = out(x,y);
|
||||
const PixelBgra& lightPixel = mapping->light(x,y);
|
||||
const PixelBgra& darkPixel = mapping->dark(x,y);
|
||||
const PixelBgra& mapPixel = mapping->map1(x,y+off);
|
||||
const PixelBgra& selPixel = mapping->map2(x,y+off);
|
||||
bool d = (selPixel.r==in.layer);
|
||||
if (!d) continue;
|
||||
int act = mapPixel.a;
|
||||
if (act<=25) continue;
|
||||
|
||||
int mod = mapPixel.b;
|
||||
int ymod = mod/16;
|
||||
int xmod = mod%16;
|
||||
double x1 = mapPixel.r + 256*xmod - RR;
|
||||
double y1 = mapPixel.g + 256*ymod - RR;
|
||||
|
||||
PixelBgra m;
|
||||
|
||||
double x12 = x1;
|
||||
double y12 = y1;
|
||||
double x13 = x1;
|
||||
double y13 = y1;
|
||||
|
||||
if (x<w-1&&y<h-1) {
|
||||
const PixelBgra& mdx = mapping->map1(x+1,y+off);
|
||||
const PixelBgra& mdy = mapping->map1(x,y+1+off);
|
||||
if (mdx.a>127 && mdy.a>127) {
|
||||
const PixelBgra& idx2 = mapping->map2(x+1,y+off);
|
||||
const PixelBgra& idx3 = mapping->map2(x,y+1+off);
|
||||
if (idx2.r==in.layer && idx3.r==in.layer) {
|
||||
int mod2 = mdx.b;
|
||||
int ymod2 = mod2/16;
|
||||
int xmod2 = mod2%16;
|
||||
x12 = mdx.r + 256*xmod2 - RR;
|
||||
y12 = mdx.g + 256*ymod2 - RR;
|
||||
|
||||
int mod3 = mdy.b;
|
||||
int ymod3 = mod3/16;
|
||||
int xmod3 = mod3%16;
|
||||
x13 = mdy.r + 256*xmod3 - RR;
|
||||
y13 = mdy.g + 256*ymod3 - RR;
|
||||
//printf("WORKING %g %g / %g %g\n", x12-x1, y12-y1,
|
||||
//x13-x1, y13-y1);
|
||||
}
|
||||
|
||||
double da = distance(x1,y1,x12,y12);
|
||||
double db = distance(x1,y1,x13,y13);
|
||||
if (da>400.0||db>400.0) {
|
||||
x12 = x1;
|
||||
y12 = y1;
|
||||
x13 = x1;
|
||||
y13 = y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x1 *= in.xs;
|
||||
y1 *= in.ys;
|
||||
double xx = in.xa*x1 + in.ya*y1;
|
||||
double yy = -in.ya*x1 + in.xa*y1;
|
||||
xx += RR + in.xo;
|
||||
yy += RR + in.yo;
|
||||
xx = in.in_x0 + active_scale*xx/RR;
|
||||
yy = in.in_y0 + active_scale*yy/RR;
|
||||
|
||||
x12 *= in.xs;
|
||||
y12 *= in.ys;
|
||||
double xxa = in.xa*x12 + in.ya*y12;
|
||||
double yya = -in.ya*x12 + in.xa*y12;
|
||||
xxa += RR + in.xo;
|
||||
yya += RR + in.yo;
|
||||
xxa = in.in_x0 + active_scale*xxa/RR;
|
||||
yya = in.in_y0 + active_scale*yya/RR;
|
||||
|
||||
x13 *= in.xs;
|
||||
y13 *= in.ys;
|
||||
double xxb = in.xa*x13 + in.ya*y13;
|
||||
double yyb = -in.ya*x13 + in.xa*y13;
|
||||
xxb += RR + in.xo;
|
||||
yyb += RR + in.yo;
|
||||
xxb = in.in_x0 + active_scale*xxb/RR;
|
||||
yyb = in.in_y0 + active_scale*yyb/RR;
|
||||
|
||||
xxa -= xx;
|
||||
yya -= yy;
|
||||
xxb -= xx;
|
||||
yyb -= yy;
|
||||
|
||||
Pixer mo = sampleLinear(in.get(),xx,yy);
|
||||
|
||||
Pixer m2 = sampleLinear(in.get(),xx+xxa/2.0,yy+yya/2.0);
|
||||
Pixer m3 = sampleLinear(in.get(),xx-xxa/2.0,yy-yya/2.0);
|
||||
Pixer m4 = sampleLinear(in.get(),xx+xxb/2.0,yy+yyb/2.0);
|
||||
Pixer m5 = sampleLinear(in.get(),xx-xxb/2.0,yy-yyb/2.0);
|
||||
|
||||
Pixer m2b = sampleLinear(in.get(),xx+(xxa+xxb)/2.0,yy+(yya+yyb)/2.0);
|
||||
Pixer m3b = sampleLinear(in.get(),xx+(xxa-xxb)/2.0,yy+(yya-yyb)/2.0);
|
||||
Pixer m4b = sampleLinear(in.get(),xx-(xxa+xxb)/2.0,yy-(yya+yyb)/2.0);
|
||||
Pixer m5b = sampleLinear(in.get(),xx-(xxa-xxb)/2.0,yy-(yya-yyb)/2.0);
|
||||
|
||||
mo = (mo*4.0 + (m2+m3+m4+m5)*2.0 + (m2b+m3b+m4b+m5b))/16.0;
|
||||
m.r = mo.r;
|
||||
m.g = mo.g;
|
||||
m.b = mo.b;
|
||||
m.a = mo.a;
|
||||
//} else {
|
||||
//m = in.get().safePixel((int)xx,(int)yy);
|
||||
//}
|
||||
|
||||
//const PixelBgra& m = in.get().safePixel((int)xx,(int)yy);
|
||||
PixelBgra result;
|
||||
if (d && act>25) {
|
||||
result.r = darkPixel.r + ((lightPixel.r-darkPixel.r)*m.r)/255;
|
||||
result.g = darkPixel.g + ((lightPixel.g-darkPixel.g)*m.g)/255;
|
||||
result.b = darkPixel.b + ((lightPixel.b-darkPixel.b)*m.b)/255;
|
||||
result.a = m.a;
|
||||
if (darkPixel.a<result.a) {
|
||||
result.a = darkPixel.a;
|
||||
}
|
||||
if (result.a>0) {
|
||||
PixelBgra& outPixel = out.pixel(x,y);
|
||||
if (result.a>250) {
|
||||
outPixel = result;
|
||||
} else {
|
||||
outPixel.r += ((result.r-outPixel.r)*result.a)/255;
|
||||
outPixel.g += ((result.g-outPixel.g)*result.a)/255;
|
||||
outPixel.b += ((result.b-outPixel.b)*result.a)/255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Render::add_simple(const Input& in) {
|
||||
check();
|
||||
double active_scale = in.in_scale;
|
||||
active_scale /= 2; //mapping->scale;
|
||||
int off = (mapping->map2.height()-mapping->light.height())/2;
|
||||
|
||||
if (mapping->map1.width()<mapping->light.width()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IMGFOR(out,x,y) {
|
||||
PixelBgra& pix = out(x,y);
|
||||
const PixelBgra& lightPixel = mapping->light(x,y);
|
||||
const PixelBgra& darkPixel = mapping->dark(x,y);
|
||||
const PixelBgra& mapPixel = mapping->map1(x,y+off);
|
||||
const PixelBgra& selPixel = mapping->map2(x,y+off);
|
||||
|
||||
int mod = mapPixel.b;
|
||||
int ymod = mod/16;
|
||||
int xmod = mod%16;
|
||||
int act = mapPixel.a;
|
||||
double x1 = mapPixel.r + 256*xmod - RR;
|
||||
double y1 = mapPixel.g + 256*ymod - RR;
|
||||
x1 *= in.xs;
|
||||
y1 *= in.ys;
|
||||
double xx = in.xa*x1 + in.ya*y1;
|
||||
double yy = -in.ya*x1 + in.xa*y1;
|
||||
xx += RR + in.xo;
|
||||
yy += RR + in.yo;
|
||||
xx = in.in_x0 + active_scale*xx/RR;
|
||||
yy = in.in_y0 + active_scale*yy/RR;
|
||||
|
||||
const PixelBgra& m = in.get().safePixel((int)xx,(int)yy);
|
||||
PixelBgra result;
|
||||
bool d = (selPixel.r==in.layer);
|
||||
if (d && act>25) {
|
||||
result.r = darkPixel.r + ((lightPixel.r-darkPixel.r)*m.r)/255;
|
||||
result.g = darkPixel.g + ((lightPixel.g-darkPixel.g)*m.g)/255;
|
||||
result.b = darkPixel.b + ((lightPixel.b-darkPixel.b)*m.b)/255;
|
||||
result.a = m.a;
|
||||
if (darkPixel.a<result.a) {
|
||||
result.a = darkPixel.a;
|
||||
}
|
||||
if (result.a>0) {
|
||||
PixelBgra& outPixel = out.pixel(x,y);
|
||||
if (result.a>250) {
|
||||
outPixel = result;
|
||||
} else {
|
||||
outPixel.r += ((result.r-outPixel.r)*result.a)/255;
|
||||
outPixel.g += ((result.g-outPixel.g)*result.a)/255;
|
||||
outPixel.b += ((result.b-outPixel.b)*result.a)/255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Render::post() {
|
||||
::render_count++;
|
||||
check();
|
||||
ImageOf<PixelBgra> pre = out;
|
||||
int w = out.width();
|
||||
int h = out.height();
|
||||
|
||||
if (mapping->map1.width()<mapping->light.width()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapping->map1.width()!=mapping->neutral.width()) return;
|
||||
if (mapping->map2.width()!=mapping->neutral.width()) return;
|
||||
|
||||
IMGFOR(out,x,y) {
|
||||
PixelBgra& pix = out(x,y);
|
||||
const PixelBgra& selPixel = mapping->map2(x,y);
|
||||
if (selPixel.b>0) {
|
||||
/*
|
||||
pix.r = 0;
|
||||
pix.g = 0;
|
||||
pix.b = 0;
|
||||
*/
|
||||
if (x>0 && y>0 && x<w-1 && y<h-1) {
|
||||
PixelBgra back1 = pre(x-1,y);
|
||||
PixelBgra idx1 = mapping->map2(x-1,y);
|
||||
|
||||
PixelBgra back2 = pre(x+1,y);
|
||||
PixelBgra idx2 = mapping->map2(x+1,y);
|
||||
|
||||
PixelBgra back3 = pre(x,y-1);
|
||||
PixelBgra idx3 = mapping->map2(x,y-1);
|
||||
|
||||
PixelBgra back4 = pre(x,y+1);
|
||||
PixelBgra idx4 = mapping->map2(x,y+1);
|
||||
|
||||
Pixer total = {0,0,0,0};
|
||||
double ct = 0;
|
||||
|
||||
if (idx1.b<127) {
|
||||
total += back1;
|
||||
ct++;
|
||||
}
|
||||
|
||||
if (idx2.b<127) {
|
||||
total += back2;
|
||||
ct++;
|
||||
}
|
||||
|
||||
if (idx3.b<127) {
|
||||
total += back3;
|
||||
ct++;
|
||||
}
|
||||
|
||||
if (idx4.b<127) {
|
||||
total += back4;
|
||||
ct++;
|
||||
}
|
||||
|
||||
if (ct>0.5) {
|
||||
total = total/ct;
|
||||
pix.r = total.r;
|
||||
pix.g = total.g;
|
||||
pix.b = total.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Render::auto_zoom(Input& in) {
|
||||
check();
|
||||
double active_scale = in.in_scale;
|
||||
active_scale /= 2; //mapping->scale;
|
||||
int off = (mapping->map2.height()-mapping->light.height())/2;
|
||||
|
||||
if (mapping->map1.width()<mapping->light.width()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double x_min = in.get().width();
|
||||
double x_max = 0;
|
||||
double y_min = in.get().height();
|
||||
double y_max = 0;
|
||||
|
||||
IMGFOR(mapping->light,x,y) {
|
||||
const PixelBgra& lightPixel = mapping->light(x,y);
|
||||
const PixelBgra& darkPixel = mapping->dark(x,y);
|
||||
const PixelBgra& mapPixel = mapping->map1(x,y+off);
|
||||
const PixelBgra& selPixel = mapping->map2(x,y+off);
|
||||
|
||||
int mod = mapPixel.b;
|
||||
int ymod = mod/16;
|
||||
int xmod = mod%16;
|
||||
int act = mapPixel.a;
|
||||
double x1 = mapPixel.r + 256*xmod - RR;
|
||||
double y1 = mapPixel.g + 256*ymod - RR;
|
||||
x1 *= in.xs;
|
||||
y1 *= in.ys;
|
||||
double xx = in.xa*x1 + in.ya*y1;
|
||||
double yy = -in.ya*x1 + in.xa*y1;
|
||||
xx += RR + in.xo;
|
||||
yy += RR + in.yo;
|
||||
xx = in.in_x0 + active_scale*xx/RR;
|
||||
yy = in.in_y0 + active_scale*yy/RR;
|
||||
|
||||
const PixelBgra& m = in.get().safePixel((int)xx,(int)yy);
|
||||
PixelBgra result;
|
||||
bool d = (selPixel.r==1);
|
||||
if (d && act>25) {
|
||||
if (xx<x_min) x_min = xx;
|
||||
if (xx>x_max) x_max = xx;
|
||||
if (yy<y_min) y_min = yy;
|
||||
if (yy>y_max) y_max = yy;
|
||||
}
|
||||
}
|
||||
double ww = in.get().width();
|
||||
double hh = in.get().height();
|
||||
dbg_printf("zoom %g %g %g %g (%g %g)\n", x_min, y_min, x_max, y_max, ww, hh);
|
||||
if (y_max-y_min<hh*0.75) {
|
||||
in.xs *= 2;
|
||||
in.ys *= 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Render::apply_scaled(const Inputs& ins, int w, int h) {
|
||||
pre();
|
||||
const std::vector<Input>& data = ins.get();
|
||||
for (std::vector<Input>::const_iterator it = data.begin();
|
||||
it != data.end(); it++) {
|
||||
add(*it);
|
||||
}
|
||||
post();
|
||||
if (w>0&&h>0 && (w!=out.width()||h!=out.height())) {
|
||||
int wi = out.width();
|
||||
int hi = out.height();
|
||||
|
||||
// we have wi,hi - want to present it in w,h
|
||||
// pad with whitespace if needed to preserve aspect ratio
|
||||
double fi = (double)wi/hi;
|
||||
double f = (double)w/h;
|
||||
|
||||
int xo = 0;
|
||||
int yo = 0;
|
||||
int wo = w;
|
||||
int ho = h;
|
||||
|
||||
out_scaled.resize(w,h);
|
||||
|
||||
if (fi>f+0.001) {
|
||||
// input is wider than output
|
||||
// pad top, bottom
|
||||
wo = w;
|
||||
ho = (int)(wo/fi);
|
||||
yo = (h-ho)/2;
|
||||
} else if (fi<f-0.001) {
|
||||
// input is thinner than output (or same)
|
||||
// pad left, right
|
||||
ho = h;
|
||||
wo = (int)(h*fi);
|
||||
xo = (w-wo)/2;
|
||||
}
|
||||
|
||||
if (xo!=0||yo!=0) {
|
||||
IMGFOR(out_scaled,x,y) {
|
||||
out_scaled(x,y) = PixelBgra(255,255,255,0);
|
||||
}
|
||||
}
|
||||
|
||||
gdImageStruct src;
|
||||
src.trueColor = true;
|
||||
src.sx = out.width();
|
||||
src.sy = out.height();
|
||||
src.cx1 = src.cy1 = 0;
|
||||
src.cx2 = src.sx-1;
|
||||
src.cy2 = src.sy-1;
|
||||
src.trueColor = true;
|
||||
src.tpixels = (int**)out.getRowArray();
|
||||
|
||||
gdImageStruct dest;
|
||||
dest.trueColor = true;
|
||||
dest.sx = out_scaled.width();
|
||||
dest.sy = out_scaled.height();
|
||||
dest.cx1 = dest.cy1 = 0;
|
||||
dest.cx2 = dest.sx-1;
|
||||
dest.cy2 = dest.sy-1;
|
||||
dest.trueColor = true;
|
||||
dest.tpixels = (int**)out_scaled.getRowArray();
|
||||
dest.saveAlphaFlag = 1;
|
||||
dest.alphaBlendingFlag = 0;
|
||||
|
||||
gdImageCopyResampled(&dest,&src,xo,yo,0,0,wo,ho,
|
||||
src.sx,src.sy);
|
||||
|
||||
IMGFOR(out_scaled,x,y) {
|
||||
out_scaled(x,y).a = 255;
|
||||
}
|
||||
|
||||
out.resize(1,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Render::auto_zoom(Inputs& ins) {
|
||||
std::vector<Input>& data = ins.get_mod();
|
||||
bool changed = false;
|
||||
for (std::vector<Input>::iterator it = data.begin();
|
||||
it != data.end(); it++) {
|
||||
changed = changed || auto_zoom(*it);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
73
src/Render.h
Normal file
73
src/Render.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef RENDER_INC
|
||||
#define RENDER_INC
|
||||
|
||||
#include "Mapping.h"
|
||||
#include "Filer.h"
|
||||
#include "Input.h"
|
||||
#include "Inputs.h"
|
||||
|
||||
class Render {
|
||||
private:
|
||||
const Mapping *mapping;
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra> out;
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra> out_scaled;
|
||||
|
||||
// active variables
|
||||
|
||||
public:
|
||||
Render() {
|
||||
mapping = 0 /*NULL*/;
|
||||
}
|
||||
|
||||
void check();
|
||||
|
||||
void attach_mapping(const Mapping *mapping) {
|
||||
if (!mapping) return;
|
||||
this->mapping = mapping;
|
||||
}
|
||||
|
||||
void pre() {
|
||||
check();
|
||||
out.setQuantum(1);
|
||||
out.copy(this->mapping->neutral);
|
||||
}
|
||||
|
||||
void add_simple(const Input& in);
|
||||
|
||||
void add(const Input& in);
|
||||
|
||||
void apply(const Inputs& ins) {
|
||||
apply_scaled(ins,-1,-1);
|
||||
}
|
||||
|
||||
void apply_scaled(const Inputs& ins, int w, int h);
|
||||
|
||||
bool auto_zoom(Inputs& ins);
|
||||
|
||||
bool auto_zoom(Input& in);
|
||||
|
||||
void post();
|
||||
|
||||
bool save(const char *fname) {
|
||||
Filer filer;
|
||||
filer.save(fname,get_mod());
|
||||
return true;
|
||||
}
|
||||
|
||||
const yarp::sig::ImageOf<yarp::sig::PixelBgra>& get() {
|
||||
return get_mod();
|
||||
}
|
||||
|
||||
yarp::sig::ImageOf<yarp::sig::PixelBgra>& get_mod() {
|
||||
if (out_scaled.width()>0) {
|
||||
return out_scaled;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static int render_count();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
48
src/Renders.cpp
Normal file
48
src/Renders.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "Renders.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Renders::check() {
|
||||
if (!repo) {
|
||||
fprintf(stderr,"No repository!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!inputs) {
|
||||
fprintf(stderr,"No inputs!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Render *Renders::get_render(int index) {
|
||||
check();
|
||||
map<int,Render>::iterator it = renders.find(index);
|
||||
if (it == renders.end()) {
|
||||
Render& render = renders[index] = Render();
|
||||
render.attach_mapping(repo->get_mapping(index));
|
||||
render.apply_scaled(*inputs,w,h);
|
||||
int rct = (int)renders.size();
|
||||
if (rct>peak_cache_count) peak_cache_count = rct;
|
||||
return &render;
|
||||
}
|
||||
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void Renders::remove_render(int index) {
|
||||
map<int,Render>::iterator it = renders.find(index);
|
||||
if (it!=renders.end()) {
|
||||
renders.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Renders::auto_zoom() {
|
||||
check();
|
||||
Render render;
|
||||
render.attach_mapping(repo->get_mapping(0));
|
||||
return render.auto_zoom(*inputs);
|
||||
}
|
||||
58
src/Renders.h
Normal file
58
src/Renders.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef RENDERS_INC
|
||||
#define RENDERS_INC
|
||||
|
||||
#include "Inputs.h"
|
||||
#include "Repository.h"
|
||||
#include "Render.h"
|
||||
|
||||
class Renders {
|
||||
private:
|
||||
Inputs *inputs;
|
||||
Repository *repo;
|
||||
std::map<int,Render> renders;
|
||||
int w, h;
|
||||
int peak_cache_count;
|
||||
|
||||
public:
|
||||
Renders() {
|
||||
inputs = 0 /*NULL*/;
|
||||
repo = 0 /*NULL*/;
|
||||
w = h = -1;
|
||||
peak_cache_count = 0;
|
||||
}
|
||||
|
||||
void check();
|
||||
|
||||
void set_size(int w, int h) {
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
}
|
||||
|
||||
void attach_repository(Repository *repo) {
|
||||
this->repo = repo;
|
||||
}
|
||||
|
||||
void attach_inputs(Inputs *inputs) {
|
||||
this->inputs = inputs;
|
||||
}
|
||||
|
||||
bool auto_zoom();
|
||||
|
||||
Render *get_render(int index = 0);
|
||||
|
||||
void remove_render(int index);
|
||||
|
||||
void remove_mapping(int index) {
|
||||
repo->remove_mapping(index);
|
||||
}
|
||||
|
||||
int length() {
|
||||
return repo->length();
|
||||
}
|
||||
|
||||
int peak() {
|
||||
return peak_cache_count;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
185
src/Repository.cpp
Normal file
185
src/Repository.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "Repository.h"
|
||||
#include "Prop.h"
|
||||
#include "Dbg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace yarp::os;
|
||||
|
||||
void Repository::load_part(const char *postfix, int idx) {
|
||||
string base = "Disp";
|
||||
if (idx==-2) base = "Thumb";
|
||||
string dark = base + "DarkData";
|
||||
string light = base + "LightData";
|
||||
string neutral = base + "TransparentData";
|
||||
string map1 = base + "MapData";
|
||||
string map2 = base + "SelData";
|
||||
if (postfix[0]!='\0') {
|
||||
dark += postfix;
|
||||
light += postfix;
|
||||
neutral += postfix;
|
||||
map1 += postfix;
|
||||
map2 += postfix;
|
||||
}
|
||||
|
||||
if (mappings.find(idx)==mappings.end()) {
|
||||
mappings[idx] = Mapping();
|
||||
}
|
||||
|
||||
Mapping& s = mappings[idx];
|
||||
bool ok = inventory.check(dark.c_str()) &&
|
||||
inventory.check(light.c_str()) &&
|
||||
inventory.check(map1.c_str()) &&
|
||||
inventory.check(map2.c_str());
|
||||
if (!ok) {
|
||||
fprintf(stderr,"Missing some map data (%s/%s/%s/%s)\n",
|
||||
dark.c_str(), light.c_str(), map1.c_str(), map2.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
bool have_neutral = inventory.check(neutral.c_str());
|
||||
|
||||
ConstString light_name = inventory.find(light.c_str()).asString();
|
||||
ConstString dark_name = inventory.find(dark.c_str()).asString();
|
||||
ConstString neutral_name = inventory.find(neutral.c_str()).asString();
|
||||
ConstString map1_name = inventory.find(map1.c_str()).asString();
|
||||
ConstString map2_name = inventory.find(map2.c_str()).asString();
|
||||
|
||||
dbg_printf("Loading light %s\n", light_name.c_str());
|
||||
if (!filer.load(light_name.c_str(),s.light)) exit(1);
|
||||
s.light_name = light_name;
|
||||
dbg_printf("Loading dark\n");
|
||||
if (!filer.load(dark_name.c_str(),s.dark)) exit(1);
|
||||
s.dark_name = dark_name;
|
||||
dbg_printf("Loading map1\n");
|
||||
if (!filer.load(map1_name.c_str(),s.map1)) exit(1);
|
||||
s.map1_name = map1_name;
|
||||
dbg_printf("Loading map2\n");
|
||||
if (!filer.load(map2_name.c_str(),s.map2)) exit(1);
|
||||
s.map2_name = map2_name;
|
||||
if (have_neutral) {
|
||||
dbg_printf("Loading neutral\n");
|
||||
if (!filer.load(neutral_name.c_str(),s.neutral)) exit(1);
|
||||
s.neutral_name = neutral_name;
|
||||
} else {
|
||||
s.neutral = s.light;
|
||||
s.neutral_name = light_name;
|
||||
}
|
||||
|
||||
s.scale = 1;
|
||||
}
|
||||
|
||||
void Repository::load(const char *fname) {
|
||||
bool ok = filer.load_zip(fname);
|
||||
if (!ok) {
|
||||
fprintf(stderr,"Cannot load zip %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Prop prop;
|
||||
|
||||
std::string txt = filer.load_text("MakeSweetConfig.hx");
|
||||
if (txt=="") {
|
||||
dbg_printf("No config file\n");
|
||||
}
|
||||
|
||||
prop.scan_hx(txt,config);
|
||||
|
||||
txt = filer.load_text("inventory.xml");
|
||||
if (txt=="") {
|
||||
fprintf(stderr, "No inventory file\n");
|
||||
exit(1);
|
||||
}
|
||||
prop.scan_xml(txt,inventory);
|
||||
|
||||
dbg_printf("Props: %s\n", config.toString().c_str());
|
||||
dbg_printf("Inventory: %s\n", inventory.toString().c_str());
|
||||
|
||||
flag_animation = false;
|
||||
if (config.check("animation",Value(0)).asInt()) {
|
||||
flag_animation = true;
|
||||
} else {
|
||||
flag_animation = false;
|
||||
}
|
||||
frames = 1;
|
||||
if (flag_animation) {
|
||||
frames = config.check("frames",Value(1)).asInt();
|
||||
}
|
||||
|
||||
dbg_printf("Loaded all files / animation %d\n", flag_animation);
|
||||
}
|
||||
|
||||
|
||||
Mapping *Repository::get_mapping(int index) {
|
||||
if (index<0) {
|
||||
map<int,Mapping>::iterator it = mappings.find(index);
|
||||
if (it == mappings.end()) {
|
||||
load_part("",index);
|
||||
it = mappings.find(index);
|
||||
}
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
if (!flag_animation) {
|
||||
map<int,Mapping>::iterator it = mappings.find(0);
|
||||
if (it == mappings.end()) {
|
||||
load_part("",0);
|
||||
it = mappings.find(0);
|
||||
int rct = (int)mappings.size();
|
||||
if (rct>peak_cache_count) peak_cache_count = rct;
|
||||
}
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
map<int,Mapping>::iterator it = mappings.find(index);
|
||||
if (it == mappings.end()) {
|
||||
char buf[256];
|
||||
sprintf(buf,"%d", index);
|
||||
load_part(buf,index);
|
||||
it = mappings.find(index);
|
||||
int rct = (int)mappings.size();
|
||||
if (rct>peak_cache_count) peak_cache_count = rct;
|
||||
}
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void Repository::remove_mapping(int index) {
|
||||
map<int,Mapping>::iterator it = mappings.find(index);
|
||||
if (it!=mappings.end()) {
|
||||
mappings.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<int> Repository::get_palette() {
|
||||
vector<int> frames;
|
||||
Bottle *lst = config.find("palette").asList();
|
||||
if (!lst) {
|
||||
int idx = config.find("palette").asInt();
|
||||
frames.push_back(idx);
|
||||
return frames;
|
||||
}
|
||||
for (int i=0; i<lst->size(); i++) {
|
||||
frames.push_back(lst->get(i).asInt());
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
double Repository::get_period() {
|
||||
double period = config.check("delay",Value(1.0)).asDouble();
|
||||
double speed = config.check("speed_step",Value(1.0)).asDouble();
|
||||
return period*speed;
|
||||
}
|
||||
|
||||
double Repository::get_hold() {
|
||||
double hold = config.check("hold",Value(1.0)).asDouble();
|
||||
return hold;
|
||||
}
|
||||
|
||||
double Repository::get_zoom() {
|
||||
double zoom = config.check("zoom",Value(1.0)).asDouble();
|
||||
return zoom;
|
||||
}
|
||||
|
||||
61
src/Repository.h
Normal file
61
src/Repository.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef REPOSITORY_INC
|
||||
#define REPOSITORY_INC
|
||||
|
||||
#include <yarp/os/Property.h>
|
||||
#include "Mapping.h"
|
||||
#include "Filer.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class Repository {
|
||||
private:
|
||||
yarp::os::Property inventory;
|
||||
yarp::os::Property config;
|
||||
std::map<int,Mapping> mappings;
|
||||
Filer filer;
|
||||
bool flag_animation;
|
||||
int frames;
|
||||
int peak_cache_count;
|
||||
|
||||
public:
|
||||
Repository() {
|
||||
flag_animation = false;
|
||||
frames = 0;
|
||||
peak_cache_count = 0;
|
||||
}
|
||||
|
||||
void load_part(const char *postfix, int idx);
|
||||
|
||||
void load(const char *fname);
|
||||
|
||||
Mapping *get_mapping(int index = 0);
|
||||
|
||||
Mapping *get_thumb_mapping() {
|
||||
return get_mapping(-2);
|
||||
}
|
||||
|
||||
void remove_mapping(int index);
|
||||
|
||||
bool is_animation() {
|
||||
return flag_animation;
|
||||
}
|
||||
|
||||
int length() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
std::vector<int> get_palette();
|
||||
|
||||
double get_period();
|
||||
|
||||
double get_hold();
|
||||
|
||||
double get_zoom();
|
||||
|
||||
int peak() {
|
||||
return peak_cache_count;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
129
src/anim_thumb.cpp
Normal file
129
src/anim_thumb.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Filer.h"
|
||||
|
||||
using namespace yarp::sig;
|
||||
|
||||
int __ms_verbose = 0;
|
||||
|
||||
bool fetch_image(ImageOf<PixelRgba>& img,
|
||||
const char *prefix,
|
||||
const char *mode,
|
||||
int index) {
|
||||
Filer filer;
|
||||
char buf[1000];
|
||||
snprintf(buf,sizeof(buf),"%s%d_%s.png",prefix,index,mode);
|
||||
bool ok = filer.load(buf,img);
|
||||
if (!ok) {
|
||||
printf("Failed to load %s\n", buf);
|
||||
exit(1);
|
||||
} else {
|
||||
printf("Found %s\n", buf);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool save_image(ImageOf<PixelRgba>& img,
|
||||
const char *prefix,
|
||||
const char *mode) {
|
||||
Filer filer;
|
||||
char buf[1000];
|
||||
snprintf(buf,sizeof(buf),"%sall_%s.png",prefix,mode);
|
||||
bool ok = filer.save(buf,img);
|
||||
if (!ok) {
|
||||
printf("Failed to save %s\n", buf);
|
||||
exit(1);
|
||||
} else {
|
||||
printf("Made %s\n", buf);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void add(ImageOf<PixelRgba>& ilight,
|
||||
ImageOf<PixelRgba>& olight,
|
||||
int i,
|
||||
int N) {
|
||||
int iw = 0;
|
||||
int ih = 0;
|
||||
int ow = 0;
|
||||
int oh = 0;
|
||||
int tw = 0;
|
||||
int th = 0;
|
||||
float twe = 0;
|
||||
float the = 0;
|
||||
iw = ilight.width();
|
||||
ih = ilight.height();
|
||||
if (iw<=1) {
|
||||
return;
|
||||
}
|
||||
tw = iw/8;
|
||||
th = ih/8;
|
||||
twe = iw/8.0;
|
||||
the = ih/8.0;
|
||||
ow = iw;
|
||||
oh = th;
|
||||
ImageOf<PixelRgba> tmp;
|
||||
tmp.copy(ilight,tw,th);
|
||||
for (int xx=0; xx<tw; xx++) {
|
||||
for (int yy=0; yy<th; yy++) {
|
||||
olight.safePixel(int(i*twe)+xx,yy) = tmp(xx,yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process() {
|
||||
const char *prefix = "/tmp/pack_makesweet/thumb_";
|
||||
int N = 8;
|
||||
int iw = 0;
|
||||
int ih = 0;
|
||||
int ow = 0;
|
||||
int oh = 0;
|
||||
int tw = 0;
|
||||
int th = 0;
|
||||
float twe = 0;
|
||||
float the = 0;
|
||||
|
||||
ImageOf<PixelRgba> olight, odark, omap, osel;
|
||||
for (int i=0; i<N; i++) {
|
||||
ImageOf<PixelRgba> ilight, idark, imap, isel;
|
||||
fetch_image(ilight,prefix,"light",i);
|
||||
fetch_image(idark,prefix,"dark",i);
|
||||
fetch_image(imap,prefix,"map",i);
|
||||
fetch_image(isel,prefix,"sel",i);
|
||||
if (iw==0) {
|
||||
iw = ilight.width();
|
||||
ih = ilight.height();
|
||||
tw = iw/8;
|
||||
th = ih/8;
|
||||
twe = iw/8.0;
|
||||
the = ih/8.0;
|
||||
ow = iw;
|
||||
oh = th;
|
||||
olight.resize(ow,oh);
|
||||
odark.resize(ow,oh);
|
||||
omap.resize(ow,oh);
|
||||
osel.resize(ow,oh);
|
||||
olight.zero();
|
||||
odark.zero();
|
||||
omap.zero();
|
||||
osel.zero();
|
||||
}
|
||||
|
||||
add(ilight,olight,i,N);
|
||||
add(idark,odark,i,N);
|
||||
add(isel,osel,i,N);
|
||||
add(imap,omap,i,N);
|
||||
}
|
||||
save_image(olight,prefix,"light");
|
||||
save_image(odark,prefix,"dark");
|
||||
save_image(omap,prefix,"map");
|
||||
save_image(osel,prefix,"sel");
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("Animation thumbnail\n");
|
||||
process();
|
||||
return 0;
|
||||
}
|
||||
|
||||
196
src/dither.cpp
Normal file
196
src/dither.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
#include <yarp/sig/ImageFile.h>
|
||||
#include <yarp/sig/ImageDraw.h>
|
||||
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::sig::file;
|
||||
|
||||
typedef ImageOf<PixelMono> Matrix;
|
||||
|
||||
Matrix getDither2x2() {
|
||||
Matrix m;
|
||||
m.resize(2,2);
|
||||
m(0,0) = 0;
|
||||
m(1,0) = 2;
|
||||
m(0,1) = 3;
|
||||
m(1,1) = 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
Matrix doubleDither(const Matrix& a) {
|
||||
Matrix b;
|
||||
int w = a.width();
|
||||
b.resize(w*2,w*2);
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int j=0; j<2; j++) {
|
||||
for (int ii=0; ii<w; ii++) {
|
||||
for (int jj=0; jj<w; jj++) {
|
||||
b(ii+i*w,jj+j*w) = a(ii,jj)*4 + a(i*(w/2),j*(w/2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
Matrix directDither(int c) {
|
||||
int w = 1;
|
||||
for (int i=0; i<c; i++) {
|
||||
w*=2;
|
||||
}
|
||||
Matrix m;
|
||||
m.resize(w,w);
|
||||
int r = w/2;
|
||||
int rr = r;
|
||||
m(0,0) = 0;
|
||||
m(r,0) = 2;
|
||||
m(0,r) = 3;
|
||||
m(r,r) = 1;
|
||||
for (int k=1; k<c; k++) {
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int j=0; j<2; j++) {
|
||||
for (int ii=0; ii<2; ii++) {
|
||||
for (int jj=0; jj<2; jj++) {
|
||||
if (ii+jj>0) {
|
||||
m(ii*r/2+i*r,jj*r/2+j*r) =
|
||||
m(ii*r,jj*r)*4 + a(i*(w/2),j*(w/2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r /= 2;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void codeDither(const Matrix& m) {
|
||||
printf("static private var rawDither : Array<Int> = [ ");
|
||||
for (int i=0; i<m.width(); i++) {
|
||||
for (int j=0; j<m.height(); j++) {
|
||||
int v = m(i,j);
|
||||
v = int(((1.0+v)/(1.0+m.width()*m.width()))*256.0);
|
||||
printf("%s0x%02x%02x%02x%02x",
|
||||
(j>0||i>0)?", ":"",
|
||||
255, v, v, v);
|
||||
}
|
||||
}
|
||||
printf(" ];\n");
|
||||
printf("static private var rawDitherDim : Int = %d;\n", m.width());
|
||||
}
|
||||
|
||||
void codeDither2(const Matrix& m) {
|
||||
printf("static int raw_dither[%d][%d] = { ", m.width(), m.height());
|
||||
for (int i=0; i<m.width(); i++) {
|
||||
if (i>0) printf(", ");
|
||||
printf("{");
|
||||
for (int j=0; j<m.height(); j++) {
|
||||
int v = m(i,j);
|
||||
v = int(((1.0+v)/(1.0+m.width()*m.width()))*256.0);
|
||||
printf("%s%d",
|
||||
(j>0)?", ":"",
|
||||
v);
|
||||
}
|
||||
printf("}");
|
||||
}
|
||||
printf(" };\n");
|
||||
printf("static int raw_dither_dim = %d;\n", m.width());
|
||||
}
|
||||
|
||||
void showDither(const Matrix& m) {
|
||||
for (int i=0; i<m.width(); i++) {
|
||||
for (int j=0; j<m.height(); j++) {
|
||||
printf("%d ", m(i,j));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
codeDither(m);
|
||||
codeDither2(m);
|
||||
}
|
||||
|
||||
void dithers() {
|
||||
Matrix d2 = getDither2x2();
|
||||
showDither(d2);
|
||||
Matrix d4 = doubleDither(d2);
|
||||
showDither(d4);
|
||||
Matrix d8 = doubleDither(d4);
|
||||
showDither(d8);
|
||||
Matrix d16 = doubleDither(d8);
|
||||
showDither(d16);
|
||||
}
|
||||
|
||||
int c2p(int c,float tweak) {
|
||||
int v = int(6*(c/256.0+tweak)+0.5);
|
||||
if (v<0) return 0;
|
||||
if (v>=6) return 5;
|
||||
return v;
|
||||
}
|
||||
|
||||
int p2c(int p) {
|
||||
return 51*p;
|
||||
}
|
||||
|
||||
int rgb2pal(const PixelRgb& pix,float tweak) {
|
||||
int v = 36*c2p(pix.r,tweak) + 6*c2p(pix.g,tweak) + c2p(pix.b,tweak);
|
||||
}
|
||||
|
||||
void pal2rgb(int pal, PixelRgb& pix) {
|
||||
int bb = pal%6;
|
||||
pal /= 6;
|
||||
int gg = pal%6;
|
||||
pal /= 6;
|
||||
int rr = pal;
|
||||
pix.r = p2c(rr);
|
||||
pix.g = p2c(gg);
|
||||
pix.b = p2c(bb);
|
||||
}
|
||||
|
||||
void dither(ImageOf<PixelRgb>& src, ImageOf<PixelRgb>& dest) {
|
||||
Matrix d = doubleDither(getDither2x2());
|
||||
//Matrix d = doubleDither(doubleDither(getDither2x2()));
|
||||
//Matrix d = doubleDither(doubleDither(doubleDither(getDither2x2())));
|
||||
showDither(d);
|
||||
write(d,"dither.ppm");
|
||||
int dd = d.width();
|
||||
|
||||
dest.resize(src);
|
||||
IMGFOR(src,x,y) {
|
||||
int dx = x%dd;
|
||||
int dy = y%dd;
|
||||
int dith = d(dx,dy);
|
||||
|
||||
int pal = rgb2pal(src(x,y),(1.0+dith)/(1.0+dd*dd)-0.5);
|
||||
pal2rgb(pal,dest(x,y));
|
||||
//dest(x,y).r = x%256;
|
||||
//dest(x,y).g = y%256;
|
||||
//dest(x,y).b = (x+y)%256;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
dithers();
|
||||
return 1;
|
||||
|
||||
if (argc<2) {
|
||||
printf("Need an in file, out file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *input_name = argv[1];
|
||||
char *output_name = argv[2];
|
||||
printf("Loading %s\n", input_name);
|
||||
ImageOf<PixelRgb> input, output;
|
||||
bool ok = read(input,input_name);
|
||||
if (!ok) {
|
||||
printf("Failed to load\n");
|
||||
return 1;
|
||||
}
|
||||
dither(input,output);
|
||||
printf("Writing %s\n", output_name);
|
||||
write(output,output_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
15
src/gd_mod.h
Normal file
15
src/gd_mod.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void *pf_gdQuantizeInit (gdImagePtr oim, gdImagePtr nim);
|
||||
extern void pf_gdQuantizeApply (void *v, gdImagePtr oim, int dither, gdImagePtr nim);
|
||||
extern void pf_gdQuantizeFini (void *v);
|
||||
|
||||
//#define pf_gdQuantizeInit gdQuantizeInit
|
||||
//#define pf_gdQuantizeApply gdQuantizeApply
|
||||
//#define pf_gdQuantizeFini gdQuantizeFini
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
2221
src/gd_topal.c
Normal file
2221
src/gd_topal.c
Normal file
File diff suppressed because it is too large
Load Diff
470
src/msmap.c
Normal file
470
src/msmap.c
Normal file
@@ -0,0 +1,470 @@
|
||||
|
||||
#include "msmap.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define PAULFITZ_MAXWIDTH 4000
|
||||
#define PAULFITZ_MAXHEIGHT 4000
|
||||
#define PAULFITZ_MAXLAYER 2
|
||||
|
||||
//#define DBG
|
||||
//#define DISABLE_ME
|
||||
|
||||
int paulfitz_px, paulfitz_py, paulfitz_active = 0;
|
||||
int paulfitz_max_layer = 0;
|
||||
float paulfitz_xx[PAULFITZ_MAXLAYER][PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
float paulfitz_yy[PAULFITZ_MAXLAYER][PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
//float paulfitz_xx2[PAULFITZ_MAXLAYER][PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
//float paulfitz_yy2[PAULFITZ_MAXLAYER][PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
int paulfitz_ct[PAULFITZ_MAXLAYER][PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
char paulfitz_idx[PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
char paulfitz_ray[PAULFITZ_MAXWIDTH][PAULFITZ_MAXHEIGHT];
|
||||
int paulfitz_remap[256];
|
||||
int paulfitz_remapping = 0;
|
||||
int paulfitz_setup = 0;
|
||||
int paulfitz_aux = 0;
|
||||
int paulfitz_bounce = 0;
|
||||
|
||||
int paulfitz_frame = 0;
|
||||
int paulfitz_make_map = 0;
|
||||
|
||||
// Use a tiny private function to output images in the trivial ppm format.
|
||||
// This avoids adding a dependency on another library.
|
||||
static int SavePPM(char *src, const char *filename, int w, int h) {
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
printf("cannot open file %s for writing\n", filename);
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(fp, "P6\n%d %d\n%d\n", w, h, 255);
|
||||
int i;
|
||||
for (i = 0; i < h; i++) {
|
||||
fwrite((void *) src, 1, (size_t) (w*3), fp);
|
||||
src += w*3;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msmap_render(int w, int h) {
|
||||
|
||||
msmap_render_scaled(w,h,1);
|
||||
}
|
||||
|
||||
void msmap_enable() {
|
||||
paulfitz_make_map = 1;
|
||||
}
|
||||
|
||||
void msmap_set_frame(int frame) {
|
||||
paulfitz_frame = frame;
|
||||
paulfitz_setup = 0;
|
||||
}
|
||||
|
||||
int msmap_parse_name(char *name) {
|
||||
if (name==NULL || (((long unsigned int) name)<256)) {
|
||||
static int message_shown = 0;
|
||||
if (!message_shown) {
|
||||
printf("msmap_parse_name: dodgy name! (%lu)\n", (long int)name);
|
||||
message_shown = 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *refname = "__makesweet_surface_n";
|
||||
static int reflen = 21; //strlen(refname);
|
||||
int idx = -1;
|
||||
|
||||
if (name[0]=='_') {
|
||||
if (name[1]=='_') {
|
||||
if (name[2]=='m') {
|
||||
if (name[3]=='a') {
|
||||
if (strlen(name)>reflen) {
|
||||
idx = atoi(name+reflen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
static const char *refname = "mkswt_";
|
||||
static int reflen = 6; //strlen(refname);
|
||||
static char buf[256];
|
||||
if (name[0]=='m') {
|
||||
if (name[1]=='k') {
|
||||
if (name[2]=='s') {
|
||||
if (name[3]=='w') {
|
||||
if (strlen(name)>reflen) {
|
||||
int at = 0;
|
||||
int i = 0;
|
||||
for (i=0; i<strlen(name); i++) {
|
||||
char ch = name[i];
|
||||
if (ch=='@') break;
|
||||
if (ch>='0'&&ch<='9') {
|
||||
buf[at] = ch;
|
||||
if (at<200) at++;
|
||||
}
|
||||
}
|
||||
buf[at] = '\0';
|
||||
//idx = atoi(name+reflen)-1;
|
||||
printf("From %s got %s\n", name, buf);
|
||||
idx = atoi(buf)-1;
|
||||
printf("GOT INDEX %d\n",idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
printf("Parse %s as %d\n", name, idx);
|
||||
#endif
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void msmap_set_bounce(int bounce) {
|
||||
paulfitz_bounce = bounce;
|
||||
}
|
||||
|
||||
|
||||
void msmap_set_input(int idx, float fx, float fy) {
|
||||
//printf("Set input %d %g %g\n", idx, fx, fy);
|
||||
if (paulfitz_remapping) {
|
||||
idx = paulfitz_remap[idx];
|
||||
if (idx==-1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (idx>paulfitz_max_layer) {
|
||||
paulfitz_max_layer = idx;
|
||||
}
|
||||
#ifdef DISABLE_ME
|
||||
static int message_shown = 0;
|
||||
if (!message_shown) {
|
||||
printf("MSMAP invoked, but it is disabled so ignoring (msmap_set_input)\n");
|
||||
message_shown = 1;
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
#ifdef DBG
|
||||
printf("Set input %d %g %g\n", idx, fx, fy);
|
||||
#endif
|
||||
|
||||
static int env_checked = 0;
|
||||
static int gave_warning = 0;
|
||||
if (!env_checked) {
|
||||
char *e = getenv("MAKESWEET_MAKE_MAP");
|
||||
if (e!=NULL) {
|
||||
paulfitz_make_map = (e[0]=='1')?1:0;
|
||||
printf("MAKESWEET_MAKE_MAP variable is %d\n", paulfitz_make_map);
|
||||
}
|
||||
env_checked = 1;
|
||||
}
|
||||
if (!paulfitz_make_map) {
|
||||
#ifdef DBG
|
||||
printf("MAKESWEET_MAKE_MAP not set up, skipping\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
printf("idx is %d\n", idx);
|
||||
#endif
|
||||
if (idx>=0) {
|
||||
if (!paulfitz_active) {
|
||||
if (gave_warning<10) {
|
||||
printf("WARNING: IMAGEWRAPOSA without active\n");
|
||||
} else if (gave_warning == 10) {
|
||||
printf("WARNING: last warning about IMAGEWRAPOSA without active\n");
|
||||
}
|
||||
gave_warning++;
|
||||
} else {
|
||||
if (!paulfitz_setup) {
|
||||
int i, j, k;
|
||||
printf("paulfitz setting up\n");
|
||||
for (i=0; i<PAULFITZ_MAXWIDTH; i++) {
|
||||
for (j=0; j<PAULFITZ_MAXHEIGHT; j++) {
|
||||
for (k=0; k<PAULFITZ_MAXLAYER; k++) {
|
||||
paulfitz_xx[k][i][j] = 0;
|
||||
paulfitz_yy[k][i][j] = 0;
|
||||
//paulfitz_xx2[k][i][j] = 0;
|
||||
//paulfitz_yy2[k][i][j] = 0;
|
||||
paulfitz_ct[k][i][j] = 0;
|
||||
}
|
||||
paulfitz_idx[i][j] = 0;
|
||||
paulfitz_ray[i][j] = 127;
|
||||
}
|
||||
}
|
||||
printf("paulfitz set up\n");
|
||||
paulfitz_setup = 1;
|
||||
}
|
||||
float dist = 0.0;
|
||||
int ray = paulfitz_bounce;
|
||||
if (paulfitz_px>=0 && paulfitz_py>=0 &&
|
||||
paulfitz_px<PAULFITZ_MAXWIDTH &&
|
||||
paulfitz_py<PAULFITZ_MAXHEIGHT &&
|
||||
idx<PAULFITZ_MAXLAYER) {
|
||||
if (ray<=paulfitz_ray[paulfitz_px][paulfitz_py]) {
|
||||
if (ray<paulfitz_ray[paulfitz_px][paulfitz_py]) {
|
||||
int k;
|
||||
for (k=0; k<=paulfitz_max_layer; k++) {
|
||||
paulfitz_xx[k][paulfitz_px][paulfitz_py] = 0;
|
||||
paulfitz_yy[k][paulfitz_px][paulfitz_py] = 0;
|
||||
paulfitz_ct[k][paulfitz_px][paulfitz_py] = 0;
|
||||
}
|
||||
paulfitz_ray[paulfitz_px][paulfitz_py] = ray;
|
||||
}
|
||||
paulfitz_xx[idx][paulfitz_px][paulfitz_py] += fx;
|
||||
paulfitz_yy[idx][paulfitz_px][paulfitz_py] += fy;
|
||||
//paulfitz_xx2[idx][paulfitz_px][paulfitz_py] += fx*fx;
|
||||
//paulfitz_yy2[idx][paulfitz_px][paulfitz_py] += fy*fy;
|
||||
paulfitz_ct[idx][paulfitz_px][paulfitz_py]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void msmap_set_output(int rx, int ry) {
|
||||
#ifdef DBG
|
||||
printf("Set output %d %d\n", rx, ry);
|
||||
#endif
|
||||
paulfitz_px = rx;
|
||||
paulfitz_py = ry;
|
||||
paulfitz_active = 1;
|
||||
paulfitz_bounce = 0;
|
||||
}
|
||||
|
||||
|
||||
void msmap_unset_output() {
|
||||
//paulfitz_px = 0;
|
||||
//paulfitz_py = 0;
|
||||
paulfitz_active = 0;
|
||||
}
|
||||
|
||||
void msmap_set_aux(int aux) {
|
||||
paulfitz_aux = aux;
|
||||
}
|
||||
|
||||
|
||||
void msmap_render_scaled(int w, int h, int factor) {
|
||||
#ifdef DBG
|
||||
printf("Makesweet Render %d %d\n", w, h);
|
||||
#endif
|
||||
if (factor!=1) {
|
||||
printf("rescale is not implemented\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!paulfitz_setup) {
|
||||
printf("MAKESWEET no output to write\n");
|
||||
} else {
|
||||
printf("MAKESWEET writing output %dx%d\n", w, h);
|
||||
int i, j;
|
||||
int ww = w/factor, hh = h/factor; // should be 4:3 aspect ratio
|
||||
int ww2 = w, hh2 = h;
|
||||
int dx = (ww2-ww)/2; // now always 0
|
||||
int dy = (hh2-hh)/2; // now always 0
|
||||
|
||||
unsigned char *img = (unsigned char *) calloc(3,ww2*hh2);
|
||||
unsigned char *img2 = (unsigned char *) calloc(3,ww2*hh2);
|
||||
if (img!=NULL && img2!=NULL) {
|
||||
memset(img,255,3*ww2*hh2);
|
||||
memset(img2,255,3*ww2*hh2);
|
||||
for (i=0; i<ww; i++) {
|
||||
for (j=0; j<hh; j++) {
|
||||
int d = 2;
|
||||
if (!(i>=d&&j>=d&&i<ww-d&&j<hh-d)) {
|
||||
d = 0;
|
||||
}
|
||||
int d2 = 1;
|
||||
if (!(i>=d2&&j>=d2&&i<ww-d2&&j<hh-d2)) {
|
||||
d2 = 0;
|
||||
}
|
||||
int max_ct = 0;
|
||||
int tot_ct = 0;
|
||||
//float best_sig = 1e9;
|
||||
//float second_best_sig = 1e9;
|
||||
//int winner_sig = -1;
|
||||
int winner = -1;
|
||||
int k, kx, ky;
|
||||
/*
|
||||
int cts[PAULFITZ_MAXLAYER];
|
||||
//float txx[PAULFITZ_MAXLAYER];
|
||||
//float txx2[PAULFITZ_MAXLAYER];
|
||||
//float tyy[PAULFITZ_MAXLAYER];
|
||||
//float tyy2[PAULFITZ_MAXLAYER];
|
||||
//float sig2[PAULFITZ_MAXLAYER];
|
||||
for (k=0; k<=paulfitz_max_layer; k++) {
|
||||
cts[k] = 0;
|
||||
}
|
||||
for (kx=-d; kx<=d; kx++) {
|
||||
for (ky=-d; ky<=d; ky++) {
|
||||
for (k=0; k<=paulfitz_max_layer; k++) {
|
||||
cts[k] += paulfitz_ct[k][i+kx][j+ky];
|
||||
//txx[k] += paulfitz_xx[k][i+kx][j+ky];
|
||||
//txx2[k] += paulfitz_xx2[k][i+kx][j+ky];
|
||||
//tyy[k] += paulfitz_yy[k][i+kx][j+ky];
|
||||
//tyy2[k] += paulfitz_yy2[k][i+kx][j+ky];
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (k=0; k<=paulfitz_max_layer; k++) {
|
||||
//int ct = cts[k];
|
||||
int ct = paulfitz_ct[k][i][j];
|
||||
//if (ct>0) {
|
||||
//sig2[k] = txx2[k] - txx[k]*txx[k] + tyy2[k] - tyy[k]*tyy[k];
|
||||
//}
|
||||
//if (sig2[k]<best_sig) {
|
||||
//second_best_sig = best_sig;
|
||||
//best_sig = sig2[k];
|
||||
//winner_sig = k;
|
||||
//}
|
||||
if (ct>max_ct) {
|
||||
max_ct = ct;
|
||||
winner = k;
|
||||
}
|
||||
tot_ct += ct;
|
||||
}
|
||||
//if (winner_sig>=0) {
|
||||
//if (paulfitz_ct[winner_sig][i][j]>10) {
|
||||
//winner = winner_sig;
|
||||
//}
|
||||
//}
|
||||
float xx = 0;
|
||||
float yy = 0;
|
||||
int rct = 0;
|
||||
if (tot_ct>0) {
|
||||
if (max_ct>tot_ct*0.55) { // || best_sig<second_best_sig*0.8) {
|
||||
paulfitz_idx[i][j] = winner+1;
|
||||
/*
|
||||
int c = 0;
|
||||
int c2 = 0;
|
||||
for (kx=-d2; kx<=d2; kx++) {
|
||||
for (ky=-d2; ky<=d2; ky++) {
|
||||
int lct = paulfitz_ct[winner][i+kx][j+ky];
|
||||
c++;
|
||||
if (lct<1) {
|
||||
if (kx!=0||ky!=0) continue;
|
||||
lct = 1;
|
||||
}
|
||||
c2++;
|
||||
xx += paulfitz_xx[winner][i+kx][j+ky]/lct;
|
||||
yy += paulfitz_yy[winner][i+kx][j+ky]/lct;
|
||||
}
|
||||
}
|
||||
if (c!=c2) {
|
||||
int lct = paulfitz_ct[winner][i][j];
|
||||
if (lct<1) lct = 1;
|
||||
xx = paulfitz_xx[winner][i][j]/lct;
|
||||
yy = paulfitz_yy[winner][i][j]/lct;
|
||||
} else {
|
||||
xx /= c;
|
||||
yy /= c;
|
||||
}
|
||||
*/
|
||||
int lct = paulfitz_ct[winner][i][j];
|
||||
if (lct<1) lct = 1;
|
||||
xx = paulfitz_xx[winner][i][j]/lct;
|
||||
yy = paulfitz_yy[winner][i][j]/lct;
|
||||
rct = 1;
|
||||
} else {
|
||||
paulfitz_idx[i][j] = -1; // mixed-up
|
||||
}
|
||||
}
|
||||
|
||||
int q1 = 255;
|
||||
int q2 = 255;
|
||||
int q3 = 255;
|
||||
if (rct) {
|
||||
int x = (int)(xx*4096+4096+0.5);
|
||||
int y = (int)(yy*4096+4096+0.5);
|
||||
if (x>4095) x -= 4096;
|
||||
if (y>4095) y -= 4096;
|
||||
if (x>4095) x = 4095;
|
||||
if (y>4095) y = 4095;
|
||||
if (x<0) x = 0;
|
||||
if (y<0) y = 0;
|
||||
y = 4095-y;
|
||||
int p1 = x%256;
|
||||
int p2 = x/256;
|
||||
int p3 = y%256;
|
||||
int p4 = y/256;
|
||||
q1 = p1;
|
||||
q2 = p3;
|
||||
q3 = p2 + 16*p4;
|
||||
}
|
||||
if (i<ww && j<hh) {
|
||||
int at = ((hh2-1-(dy+j))*ww+dx+i)*3;
|
||||
img[at] = (unsigned char) q1;
|
||||
img[at+1] = (unsigned char) q2;
|
||||
img[at+2] = (unsigned char) q3;
|
||||
}
|
||||
}
|
||||
}
|
||||
int maxn = paulfitz_max_layer + 1;
|
||||
int tricky = 0;
|
||||
for (i=0; i<ww; i++) {
|
||||
for (j=0; j<hh; j++) {
|
||||
int idx = paulfitz_idx[i][j];
|
||||
int q1 = 255;
|
||||
int q2 = 255;
|
||||
int q3 = 255;
|
||||
|
||||
if (idx>0) {
|
||||
q1 = idx;
|
||||
q2 = idx*64;
|
||||
q3 = 0;
|
||||
} else if (idx==-1) {
|
||||
tricky = 1;
|
||||
}
|
||||
int at = ((hh2-1-(dy+j))*ww+dx+i)*3;
|
||||
img2[at] = (unsigned char) q1;
|
||||
img2[at+1] = (unsigned char) q2;
|
||||
img2[at+2] = (unsigned char) q3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SavePPM((char *)img, "mapper.ppm", ww2, hh2);
|
||||
SavePPM((char *)img2, "mapper2.ppm", ww2, hh2);
|
||||
|
||||
FILE *fout = fopen("mapper.txt","w");
|
||||
if (fout==NULL) {
|
||||
printf("cannot write to mapper.txt");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fout,"maxn=%d\n", maxn);
|
||||
fprintf(fout,"tricky=%d\n", tricky);
|
||||
|
||||
printf("PAULFITZ wrote mapper.ppm mapper2.ppm mapper.txt\n");
|
||||
free(img);
|
||||
free(img2);
|
||||
img = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
paulfitz_setup = 0;
|
||||
}
|
||||
|
||||
|
||||
int msmap_set_index(int external_index, int internal_index) {
|
||||
int i;
|
||||
if (!paulfitz_remapping) {
|
||||
paulfitz_remapping = 1;
|
||||
for (i=0; i<256; i++) {
|
||||
paulfitz_remap[i] = -1;
|
||||
}
|
||||
}
|
||||
paulfitz_remap[internal_index] = external_index;
|
||||
return 0;
|
||||
}
|
||||
25
src/msmap.h
Normal file
25
src/msmap.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef HAVE_MSMAP_H
|
||||
#define HAVE_MSMAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void msmap_enable();
|
||||
void msmap_set_frame(int frame);
|
||||
void msmap_set_aux(int is_aux);
|
||||
void msmap_set_output(int rx, int ry);
|
||||
void msmap_unset_output();
|
||||
void msmap_set_input(int index, float fx, float fy);
|
||||
void msmap_set_bounce(int bounce);
|
||||
int msmap_parse_name(char *name);
|
||||
int msmap_set_index(int external_index, int internal_index);
|
||||
void msmap_render(int w, int h);
|
||||
void msmap_render_scaled(int w, int h, int factor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
132
src/nonblend.cpp
Normal file
132
src/nonblend.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
#include <yarp/sig/ImageFile.h>
|
||||
#include <yarp/sig/ImageDraw.h>
|
||||
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::sig::file;
|
||||
|
||||
double punfix(int r) {
|
||||
return (r/255.0)*2.0-1;
|
||||
}
|
||||
|
||||
int pfix(double x) {
|
||||
x = (x+1)/2;
|
||||
int r = (int)(x*255.0+0.5);
|
||||
if (r>255) r = 255;
|
||||
if (r<0) r = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void process2(ImageOf<PixelRgb>& dest,ImageOf<PixelRgb>& overlay) {
|
||||
int w = 512;
|
||||
dest.resize(w,w);
|
||||
double maxerr = 0.0;
|
||||
IMGFOR(dest,x,y) {
|
||||
PixelRgb& pix = dest(x,y);
|
||||
PixelRgb over;
|
||||
double fx = x/((double)w);
|
||||
double fy = y/((double)w);
|
||||
// fx = [0:1)
|
||||
// fy = [0:1)
|
||||
double theta = fx*M_PI;
|
||||
double phi = fy*M_PI*2;
|
||||
double xx = sin(theta)*cos(phi);
|
||||
double yy = sin(theta)*sin(phi);
|
||||
double zz = cos(theta);
|
||||
// xx, yy, zz: [-1:1]
|
||||
int pr = pfix(xx);
|
||||
int pg = pfix(yy);
|
||||
int pb = pfix(zz);
|
||||
pix.r = pr;
|
||||
pix.g = pg;
|
||||
pix.b = pb;
|
||||
|
||||
// inversion
|
||||
double x2=punfix(pix.r);
|
||||
double y2=punfix(pix.g);
|
||||
double z2=punfix(pix.b);
|
||||
double len = sqrt(x2*x2+y2*y2+z2*z2);
|
||||
double phi2 = atan2(y2,x2);
|
||||
double theta2 = acos(z2/len);
|
||||
if (theta2<0) theta2 += M_PI;
|
||||
if (phi2<0) phi2 += M_PI*2;
|
||||
|
||||
|
||||
double theta3 = asin(sqrt(xx*xx+yy*yy));
|
||||
if (theta3<0) theta3 += M_PI;
|
||||
if (fabs(theta2-theta3)>=0.1) {
|
||||
theta3 = M_PI-theta3;
|
||||
}
|
||||
|
||||
if (fabs(theta2-theta3)<0.1) {
|
||||
theta2 = (theta2+theta3)/2;
|
||||
//printf("MATCH %g : %g\n", theta2, theta3);
|
||||
} else {
|
||||
printf("Mismatch %g : %g\n", theta2, theta3);
|
||||
}
|
||||
|
||||
double ex = (theta2/(M_PI))*w;
|
||||
double ey = (phi2/(M_PI*2.0))*w;
|
||||
double err = sqrt((ex-x)*(ex-x)+(ey-y)*(ey-y));
|
||||
if (x>5 && y>5 && x<w-6 && y<w-6) {
|
||||
//if (err>10) {
|
||||
//printf("err %g: %g %g / %d %d\n", err, ex, ey, x, y);
|
||||
//}
|
||||
if (err>8) {
|
||||
printf("len %g err %g: %g %g / %d %d\n", len, err, ex, ey, x, y);
|
||||
}
|
||||
if (err>maxerr) maxerr = err;
|
||||
}
|
||||
}
|
||||
printf("Maximum error is %g\n", maxerr);
|
||||
}
|
||||
|
||||
void process(ImageOf<PixelRgb>& dest,ImageOf<PixelRgb>& overlay) {
|
||||
int w = 512;
|
||||
dest.resize(w,w);
|
||||
IMGFOR(dest,x,y) {
|
||||
PixelRgb& pix = dest(x,y);
|
||||
PixelRgb over;
|
||||
double fx = x/((double)w-1);
|
||||
double fy = y/((double)w-1);
|
||||
pix.r = int(fx*255+0.5);
|
||||
pix.g = int(fy*255+0.5);
|
||||
if (overlay.width()>0) {
|
||||
pix.b = 255-overlay(x,y).r;
|
||||
if (pix.b==0) {
|
||||
pix.b = (pix.r%51==0||pix.g%51==0)?(((x+y)%2)?128:255):pix.b;
|
||||
}
|
||||
} else {
|
||||
pix.b = (pix.r%51==0||pix.g%51==0)?255:0;
|
||||
if (fabs(x-w/2.0)+fabs(y-w/2.0)<w/16) {
|
||||
pix.b = (y<w/2)?255:((x<w/2)?128:64);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc<2) {
|
||||
printf("Need an out file\n");
|
||||
return 1;
|
||||
}
|
||||
char *overlay_name = NULL;
|
||||
if (argc>=3) {
|
||||
overlay_name = argv[2];
|
||||
}
|
||||
|
||||
char *output_name = argv[1];
|
||||
ImageOf<PixelRgb> output, overlay;
|
||||
if (overlay_name!=NULL) {
|
||||
printf("template %s\n", overlay_name);
|
||||
read(overlay,overlay_name);
|
||||
}
|
||||
process2(output,overlay);
|
||||
printf("Writing %s\n", output_name);
|
||||
write(output,output_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
149
src/reanimator.cpp
Normal file
149
src/reanimator.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
#include <yarp/sig/ImageFile.h>
|
||||
#include <yarp/sig/ImageDraw.h>
|
||||
#include <yarp/os/Network.h>
|
||||
|
||||
#include "Filer.h"
|
||||
#include "Prop.h"
|
||||
#include "Repository.h"
|
||||
#include "Input.h"
|
||||
#include "Render.h"
|
||||
#include "Renders.h"
|
||||
#include "GifAnim.h"
|
||||
#include "Dbg.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace yarp::os;
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::sig::file;
|
||||
|
||||
int __ms_verbose = 0;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (Network::getEnvironment("VERBOSE")=="1") {
|
||||
__ms_verbose = 1;
|
||||
}
|
||||
|
||||
Property options;
|
||||
options.fromCommand(argc,argv);
|
||||
|
||||
Repository repo;
|
||||
|
||||
if (!options.check("zip")) {
|
||||
fprintf(stderr, "reanimator --zip foo.zip --in img1.png img2.png\n");
|
||||
fprintf(stderr, "reanimator ... --w 200 --h 150\n");
|
||||
fprintf(stderr, "reanimator ... --first 2\n");
|
||||
fprintf(stderr, "reanimator ... --last 4\n");
|
||||
fprintf(stderr, "reanimator ... --single\n");
|
||||
fprintf(stderr, "reanimator ... --auto_zoom\n");
|
||||
fprintf(stderr, "reanimator ... --save \"frame_%%06d.jpg\"\n");
|
||||
fprintf(stderr, "reanimator ... --gif example.gif\n");
|
||||
fprintf(stderr, "reanimator ... --stats\n");
|
||||
fprintf(stderr, "reanimator ... --files\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
repo.load(options.find("zip").asString().c_str());
|
||||
|
||||
Inputs ins;
|
||||
|
||||
Bottle& lst = options.findGroup("in");
|
||||
for (int i=1; i<lst.size(); i++) {
|
||||
Input& in = ins.add();
|
||||
in.load(lst.get(i).asString().c_str());
|
||||
in.layer = i;
|
||||
}
|
||||
|
||||
Renders renders;
|
||||
renders.attach_repository(&repo);
|
||||
renders.attach_inputs(&ins);
|
||||
if (options.check("w")&&options.check("h")) {
|
||||
renders.set_size(options.find("w").asInt(),options.find("h").asInt());
|
||||
}
|
||||
int first = options.check("first",Value(0)).asInt();
|
||||
int last = options.check("last",Value(repo.length()-1)).asInt();
|
||||
|
||||
if (options.check("single")) {
|
||||
first = last = 0;
|
||||
}
|
||||
|
||||
if (options.check("auto_zoom")) {
|
||||
renders.auto_zoom();
|
||||
}
|
||||
|
||||
if (options.check("save")) {
|
||||
for (int i=first; i<=last; i++) {
|
||||
Render *r = renders.get_render(i);
|
||||
if (!r) exit(1);
|
||||
char buf[256];
|
||||
sprintf(buf,options.check("save",Value("frame_%06d.jpg")).asString().c_str(),i);
|
||||
r->save(buf);
|
||||
dbg_printf("Wrote to %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.check("gif")) {
|
||||
GifAnim anim;
|
||||
anim.attach_renders(&renders);
|
||||
anim.set_palette(repo.get_palette());
|
||||
anim.set_timing(repo.get_period(),repo.get_hold());
|
||||
anim.apply();
|
||||
anim.save(options.find("gif").asString().c_str());
|
||||
}
|
||||
|
||||
if (options.check("files")) {
|
||||
printf("animation=%s\n", repo.is_animation()?"true":"false");
|
||||
printf("length=%d\n", repo.length());
|
||||
printf("period=%g\n", repo.get_period());
|
||||
printf("hold=%g\n", repo.get_hold());
|
||||
printf("zoom=%g\n", repo.get_zoom());
|
||||
Mapping *mapping = repo.get_mapping();
|
||||
if (mapping) {
|
||||
printf("light=\"%s\"\n", mapping->light_name.c_str());
|
||||
printf("dark=\"%s\"\n", mapping->dark_name.c_str());
|
||||
printf("map1=\"%s\"\n", mapping->map1_name.c_str());
|
||||
printf("map2=\"%s\"\n", mapping->map2_name.c_str());
|
||||
printf("neutral=\"%s\"\n", mapping->neutral_name.c_str());
|
||||
}
|
||||
mapping = repo.get_thumb_mapping();
|
||||
if (mapping) {
|
||||
printf("thumb_light=\"%s\"\n", mapping->light_name.c_str());
|
||||
printf("thumb_dark=\"%s\"\n", mapping->dark_name.c_str());
|
||||
printf("thumb_map1=\"%s\"\n", mapping->map1_name.c_str());
|
||||
printf("thumb_map2=\"%s\"\n", mapping->map2_name.c_str());
|
||||
printf("thumb_neutral=\"%s\"\n", mapping->neutral_name.c_str());
|
||||
}
|
||||
if (repo.is_animation()) {
|
||||
for (int i=0; i<repo.length(); i++) {
|
||||
char prefix[256];
|
||||
sprintf(prefix,"frame_%d_", i);
|
||||
mapping = repo.get_mapping(i);
|
||||
printf("%slight=\"%s\"\n", prefix, mapping->light_name.c_str());
|
||||
printf("%sdark=\"%s\"\n", prefix, mapping->dark_name.c_str());
|
||||
printf("%smap1=\"%s\"\n", prefix, mapping->map1_name.c_str());
|
||||
printf("%smap2=\"%s\"\n", prefix, mapping->map2_name.c_str());
|
||||
printf("%sneutral=\"%s\"\n", prefix, mapping->neutral_name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.check("stats")) {
|
||||
fprintf(stderr,"Peak number of mappings cached: %d\n", repo.peak());
|
||||
fprintf(stderr,"Peak number of renders cached: %d\n", renders.peak());
|
||||
fprintf(stderr,"Total number of frames: %d\n", repo.length());
|
||||
fprintf(stderr,"Total number of renders: %d\n",
|
||||
Render::render_count());
|
||||
fprintf(stderr,"Palette frame(s):");
|
||||
vector<int> pals = repo.get_palette();
|
||||
for (int i=0; i<(int)pals.size(); i++) {
|
||||
fprintf(stderr," %d", pals[i]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
src/reblend.cpp
Normal file
71
src/reblend.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <yarp/sig/Image.h>
|
||||
#include <yarp/sig/ImageFile.h>
|
||||
#include <yarp/sig/ImageDraw.h>
|
||||
|
||||
#include "msmap.h"
|
||||
|
||||
using namespace yarp::sig;
|
||||
using namespace yarp::sig::file;
|
||||
|
||||
|
||||
int diff(PixelRgb& p1, PixelRgb& p2) {
|
||||
return
|
||||
(p1.r-p2.r)*(p1.r-p2.r)+
|
||||
(p1.g-p2.g)*(p1.g-p2.g)+
|
||||
(p1.b-p2.b)*(p1.b-p2.b);
|
||||
}
|
||||
|
||||
void process(ImageOf<PixelRgb>& src, ImageOf<PixelRgb>& light, ImageOf<PixelRgb>& dark) {
|
||||
printf("Size %d %d\n", src.width(), src.height());
|
||||
msmap_enable();
|
||||
msmap_set_frame(0);
|
||||
int k = 2;
|
||||
int d = 2;
|
||||
IMGFOR(src,x,y) {
|
||||
PixelRgb& pix = src(x,y);
|
||||
if (pix.r>0||pix.g>0||pix.r>0) {
|
||||
PixelRgb& li = light(x,y);
|
||||
PixelRgb& da = dark(x,y);
|
||||
if (diff(li,da)>10) {
|
||||
msmap_set_output(x,src.height()-1-y);
|
||||
double fx = pix.r/255.0;
|
||||
double fy = pix.g/255.0;
|
||||
msmap_set_input(0,fx,1-fy);
|
||||
// smoothing
|
||||
for (int kk=0; kk<k; kk++) {
|
||||
for (int xx=-d; xx<=d; xx++) {
|
||||
for (int yy=-d; yy<=d; yy++) {
|
||||
if (x+xx>=0 && y+yy>=0 && x+xx<src.width() &&
|
||||
y+yy<src.height()) {
|
||||
msmap_set_aux(xx!=0||yy!=0);
|
||||
msmap_set_output(x+xx,src.height()-1-y-yy);
|
||||
msmap_set_input(0,fx,1-fy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
msmap_render(src.width(),src.height());
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc<4) {
|
||||
printf("Need an input map file, a light file, a dark file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *input_name = argv[1];
|
||||
char *light_name = argv[2];
|
||||
char *dark_name = argv[3];
|
||||
ImageOf<PixelRgb> input, light, dark;
|
||||
read(input,input_name);
|
||||
read(light,light_name);
|
||||
read(dark,dark_name);
|
||||
process(input,light,dark);
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
templates/billboard-cityscape.zip
Normal file
BIN
templates/billboard-cityscape.zip
Normal file
Binary file not shown.
BIN
templates/frog.jpg
Normal file
BIN
templates/frog.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Reference in New Issue
Block a user