Tuesday, December 30, 2008

source packed in images.



I'm sick of posting source code in the text. I want to be able to upload any file, but all they let you upload is images. I wrote some c++ code to input any file and embed the contents as the pixels of an image (will only work with lossless encoding). The source code for this example is in one of the small images in this blog (the other is the python source of the previous posting). Too bad I couldn't upload a tga,tiff,or pgm, because those files you could just open as text and see the source. I leave it up to you to extract the code from the png.


Hint: convert to pgm (gray-scale) and open with an image editor.


convert image.png p.pgm
cat p.pgm

pyJoy






We just watched Control the other night and both my girlfriend and I liked a poster in the movie. Not knowing that this was an album cover, I immediately thought I should make something like that. So I wrote a script in a couple minutes to generate some images. Source code:





import cairo, sys
import math, random

def gen_row(w, smth=10, shft=0.2, wid=0.5):
mid = w/2
shft = mid*shft
wid = mid*wid

vals = [0]*w
for x in xrange(0, w):
sc = (x-random.uniform(mid-wid, mid+wid))/random.uniform(wid*0.9, wid*1.1)
sc = math.exp(-sc*sc/2)
ht = random.uniform(0,sc)
vals[x] = ht

for i in xrange(0, smth):
v = [0]*w
for x in xrange(1, w-1):
v[x] = (vals[x] + vals[x-1] + vals[x+1])/3
vals = v

return vals

w, h = 256, 512
x0, sc = 4, 20
wid = 0.2

if len(sys.argv)>=3:
w = int(sys.argv[1])
h = int(sys.argv[2])

if len(sys.argv)>=4:
wid = float(sys.argv[3])

surf = cairo.SVGSurface('joy.svg', w, h)
ctx = cairo.Context(surf)

for y in xrange(10, h, 5):

ctx.move_to(x0, y)
row = gen_row(w, wid=wid)

for x in xrange(x0, w-x0):
ctx.line_to(x, y-row[x]*sc)

ctx.set_source_rgba(0,0,0,1)
ctx.stroke_preserve()

ctx.set_source_rgba(1,1,1,1)
ctx.line_to(w-x0, y+10)
ctx.line_to(0, y+10)
ctx.line_to(0, y)
ctx.fill()

surf.finish()

Monday, December 29, 2008

how slow is dynamic_cast?

I was wondering how slow dynamic_cast really is the other day when I considering designing something in a way that would require it's use. The other alternatives is to have some a virtual functions that performs a cast (requires the parent class to know about all children) or have a virtual function that exposes the type followed by a cast.

One of the first references I found on the web indicated the virtual-function-then-cast approach being up to 20x faster.
http://www.nerdblog.com/2006/12/how-slow-is-dynamiccast.html

That reference didn't provide code, so I wrote a quick test with the hierarchy of following classes:

ClassA, ClassB: public ClassA, and ClassC: public ClassB.

My tests suggest that this approach is about 5x faster when compiled with g++ -O3 (same speed with no optimization). For my application dynamic_cast should be perfectly fine.

Times for 3*100 million cast and function evaluations (in a smidge more than trivial loop)

Not optimized:

mycast 0m13.879s
dynamic_cast 0m0.060s


Optimized

mycast 0m0.919s
dynamic_cast 0m4.729s


a.h

class AClassA{
public:
static const int flag = 0x1;

AClassA(){}
virtual ~AClassA(){}

virtual int name() const ;

int a(){return 1;}
};

class BClassB: public AClassA {
public:
static const int flag = 0x2;

BClassB(){}
virtual ~BClassB(){}

int name() const ;

int b(){return 2;}
};

class CClassC: public BClassB {
public:
static const int flag = 0x4;
CClassC(){}
virtual ~CClassC(){}

int name() const ;

int c(){return 3;}
};


a.cc

#include "a.h"

#ifdef use_mycast
#warning "using mycast"
#define caster mycast
#define extras
#else
#define caster dynamic_cast
#define extras *
#endif

int AClassA::name() const {return AClassA::flag;}

int BClassB::name() const {return AClassA::flag | BClassB::flag;}

int CClassC::name() const {return AClassA::flag | BClassB::flag | CClassC::flag;}

template
T * mycast(AClassA * a){
if(a->name() & T::flag)return (T*)a;
}

int func_dcast(AClassA * a){
CClassC * c = caster(a);
if(c)return c->c();
else {
BClassB * b = caster(a);
if(b)return b->b();
}
return a->a();
}

int main(int ac, char * av[]){
const int ntrials = 100000000;
int sums[8] = {0,0,0,0};

AClassA a;
BClassB b;
CClassC c;

for(int i=0; i!=ntrials; i++){
sums[func_dcast(&a)]++;
sums[func_dcast(&b)]++;
sums[func_dcast(&c)]++;
}
printf("%d %d %d %d\n", sums[0], sums[1], sums[2], sums[3]);
return 0;
}



makefile

all:
g++ a.cc -Duse_mycast -o mycast.opt -O3 -fno-rtti
g++ a.cc -Duse_mycast -o mycast -fno-rtti
g++ a.cc -o dcast.opt -O3
g++ a.cc -o dcast


test.sh

echo "Unoptimized (mycast then dcast)"
time ./mycast | grep real
time ./dcast | grep real
echo "Optimimzed (mycast then dcast)"
time ./mycast.opt | grep real
time ./dcast.opt | grep real

Bitten again...and again

I think my poor long term memory is causing me to run into the same problems over and over again. One of the dumbest oversights I've made in the past (when I had no experience using a laptop), was forgetting to enable the wireless on the case before trying to connect to a network. Yesterday I was given a laptop to fix and wasn't given any indication of what was wrong. Upon booting, it seemed like someone had attempted a fresh install but had failed to complete installing all the drivers. I figured this was the only problem and set out to install the drivers. Before attempting to get wifi working I checked for the wifi toggle on the case and didn't find one; I then checked in the bios and there was only a disable or use last state option. So I just figured it was on, got driver installed which had option to enable/disable radio. After several driver installs and related utility installs with no luck when scanning for networks I noticed the function key to turn on the wifi. Can't believe I didn't look for it from the start. I knew it wasn't on but continued to repeatedly do something that wasn't working.

Another bite in the ass that I am sure I have received before (although not sure when) is due to gl_ClipVertex not being set in OpenGL shaders. I had a working graphics demo that was using reflections for water and used user-defined clip planes for rendering the reflection. The rendering is based on a scene graph that has shader nodes. Originally the rendering of the reflected image wasn't under a default shader node, meaning it was using the fixed-function pipeline. After improving the scene, everything was changed to use a different default shader, and all of a sudden the reflection wasn't correct. Assuming the change had something to do with the scene-graph, or traversal of it, I spent a bunch of time digging through other code looking for the problem, when it reality it was that I wasn't setting gl_ClipVertex. I have no idea why you would want gl_ClipVertex to be different than gl_Position. But that doesn't matter. All that matters is that I never make this mistake again.