Friday, October 23, 2009

sizeof/bsizeof

I thought it was about time that I make a few convenient changes to the old sizeof utility. The primary change here is adding support of printing either bytes (as bsizeof, which is useful for piping to sort -k1nr) or size in larger units as appropriate (as sizeof).

sizeof.c

#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>

off_t getsize(const char * path) {
off_t ret = 0;
struct stat info;
struct dirent * file;
DIR * dirinfo;
char d_name[PATH_MAX];
size_t pathlen = strlen(path);
char * app = d_name + pathlen + 1;
if(pathlen < PATH_MAX) {
strcpy(d_name, path);
strcat(d_name, "/");
if(!stat(path, &info)) {
if(S_ISREG(info.st_mode))
ret = info.st_size;
else if(S_ISDIR(info.st_mode)) {
dirinfo = opendir(path);
while((file = readdir(dirinfo)) != NULL) {
if(strcmp(".", file->d_name) && strcmp("..", file->d_name) && pathlen + file->d_reclen + 1 < PATH_MAX) {
strcpy(app, file->d_name);
ret += getsize(d_name);
}
}
closedir(dirinfo);
}
}
}
return ret;
}
int compute_size_string(char * str, off_t size) {
if(size > (1 << 30))
sprintf(str, "%.2lf GiB", ((double) size) / ((double)(1 << 30)));
else if(size > (1 << 20))
sprintf(str, "%.2lf MiB", ((double) size) / ((double)(1 << 20)));
else if(size > (1 << 10))
sprintf(str, "%.2lf kiB", ((double) size) / ((double)(1 << 10)));
else
sprintf(str, "%lu B", size);
return 0;
}
void print_size_computed(off_t size, const char * name) {
char size_string[1024];
compute_size_string(size_string, size);
printf("%-10s %s\n", size_string, name);
}
void print_size(off_t size, const char * name) {
printf("%-40lu %s\n", size, name);
}

int main(int argc, char ** argv) {
int i;
off_t size;
char * bname = basename(argv[0]);
void (* handler)(off_t, const char *) = strcmp(bname, "bsizeof") ? &print_size_computed : &print_size;
for(i = 1; i < argc; i++) {
size = getsize(argv[i]);
if(size)
handler(size, argv[i]);
}
return 0;
}

Sunday, October 18, 2009

Dream: Mountain Spring and Waterfall

I know for a fact that I've had this dream before, which is why it's interesting. The overarching plot starts off with me wanting to run away from home, and through the course I visit multiple different locations. I'll only describe the snapshots that I can recall.

  1. I start by walking down my homestreet, which isn't so abnormal. I make a left at the tee.
  2. A thought runs through my mind, "If I keep going this way, through the mountains, I'll end up in Everett." I even see the mountains in the distance. Strangely, there aren't any actual mountains between where I live and Everett in real life.
  3. I end up passing through a rural area reminiscent of the rural Cascade foothills, with light forest and a lot of grass on the slopes.
  4. Eventually, I arrive at a massive spring, where the water is clear and the bed is made of white rock. There are executives of some sort ("suits") in the water, and I mention to one that I've been in the pool before. He only utters a bit of poetry in response.
  5. My next stop is where the road I'm walking along makes a light right turn, with the stream originating from the spring separating it from the base of a cliff. A high road runs across the top of the cliff.
  6. I exit the forest, only to come to a series of waterfalls in a somewhat more barren landscape. I had been off the road for some time, instead opting for a paved path originating from it. The path splits, with one end capped with a balcony and the other direction crossing a bridge similar to this one, only using steel tubing instead of wood. The bridge crosses a very tall, yet moderately wide waterfall, which levels off for a hundred meters, then cascades down a much wider set of horseshoe falls. I take out my camera and snap photos of the scenery, but when I get to the bridge I hesitate, remembering my last experience. The bridge begins to violently sway in a manner similar to that of a boat as I try to cross it, forcing me to return to the path.
  7. I climb various other paths to take photos of odd sculptures that adorn the ridge visible from the balcony, where other tourists do the same.

It's an interesting dream, but I only recall having had it once before.

Friday, October 16, 2009

ロマンスの神様 - 広瀬香美

This song is so happy and warm that I feel like my head's going to explode with rainbows. It sounds silly, but you'd have to listen to it to see what I mean.

勇気と愛が世界を救う 絶対いつか出会えるはずなの
沈む夕日に淋しく一人 こぶし握りしめる私
週休二日 しかもフレックス 相手はどこにでもいるんだから
今夜飲み会 期待している 友達の友達に

目立つにはどうしたらいいの 一番の悩み
性格良ければいい そんなの嘘だと思いませんか?

Boy Meets Girl 幸せの予感 きっと誰かを感じてる
Fall In Love ロマンスの神様 この人でしょうか

ノリと恥じらい必要なのよ 初対面の男の人って
年齢 住所 趣味に職業 さりげなくチェックしなくちゃ
待っていました 合格ライン 早くサングラス取って見せてよ
笑顔が素敵 真顔も素敵 思わず見とれてしまうの

幸せになれるものならば 友情より愛情
「帰りは送らせて」と さっそくOK ちょっと信じられない

Boy Meets Girl 恋してる瞬間 きっとあなたを 感じてる
Fall In Love ロマンスの神様 願いをかなえて
Boy Meets Girl 恋する気持ち 何より素敵な宝物
Fall In Love ロマンスの神様 どうもありがとう

よくあたる星占いに そう言えば書いてあった
今日 会う人と結ばれる 今週も 来週も さ来週もずっと oh yeah!

Boy Meets Girl 土曜日 遊園地 一年たったらハネムーン
Fall In Love ロマンスの神様 感謝しています
Boy Meets Girl いつまでも ずっとこの気持ちを忘れたくない
Fall In Loveロ マンスの神様 どうもありがとう

Thursday, October 15, 2009

flatten.py

Working with images a lot, thanks to my webcomic, becomes a lot easier when certain things are automated. For example, this script takes care of flattening an image (by removing alpha information), and even passes the output through pngcrush when applicable. It also includes a default output convention:

flatten.py

#!/usr/bin/python
from sys import argv, stderr, exit
from subprocess import Popen
from optparse import OptionParser, OptionValueError
from os import remove
from os import close as os_close
from re import compile as re_compile
from os.path import join, isfile
from tempfile import mkstemp


size = re_compile('^(.+)x(.+)$')

def check_size(option, opt_str, value, parser):
m = size.search(value)
if m:
parser.values.size = m.group(1), m.group(2)
else:
raise OptionValueError('Invalid size: %s' % value)

filext = re_compile('^(.+)\.(.+)$')
filext_png = re_compile('\.png$')

img_type = ['Bilevel', 'Grayscale', 'GrayscaleMatte', 'Palette', 'PaletteMatte', 'TrueColor', 'TrueColorMatte', 'ColorSeparate', 'ColorSeparationMatte', 'Optimize']
img_cspace = ['CMY', 'CMYK', 'Gray', 'HSB', 'HSL', 'HWB', 'Lab', 'Log', 'OHTA', 'Rec601Luma', 'Rec601YCbCr', 'Rec709Luma', 'Rec709YCbCr', 'RGB', 'sRGB', 'Transparent', 'XYZ', 'YCbCr', 'YCC', 'YIQ', 'YPbPr', 'YUV']

parser = OptionParser(usage = 'Usage: %prog [ options ] input [ output ]')
parser.add_option('-s', '--size', dest = 'size', type = 'string', action = 'callback', callback = check_size, default = None, help = 'The output size: WIDTHxHEIGHT')
parser.add_option('-n', '--no-clobber', dest = 'clobber', default = True, action = 'store_false', help = 'The output size: WIDTHxHEIGHT')
parser.add_option('-f', '--filter', dest = 'filter', default = 'Catrom', help = 'The filter to resize with if necessary.')
parser.add_option('-b', '--background', dest = 'background', default = 'white', help = 'The background when flattening.')
parser.add_option('-F', '--no-flatten', dest = 'flatten', default = True, action = 'store_false', help = 'Don\'t flatten the output.')
parser.add_option('-t', '--type', dest = 'type', type = 'string', default = None, help = 'The type of the output image: analogous to both -type and -colorspace in ImageMagick')
parser.add_option('-d', '--depth', dest = 'depth', type = 'int', default = None, help = 'The depth of the output image.')

options, args = parser.parse_args()
if len(args):
input = args.pop(0)
if isfile(input):
output = None
pngout = False
if len(args):
output = args.pop(0)
if filext_png.search(output):
pngout = True
else:
m = filext.search(input)
if not m is None:
output = '%s_small.%s' % (m.group(1), m.group(2))
if m.group(2) == 'png':
pngout = True
else:
output = '%s_small.png' % input
pngout = True
if not options.clobber and isfile(output):
print >>stderr, 'Output file exists:', output
exit(2)
# ACTUAL PROCESSING
args = ['convert', input]

if options.flatten:
args += ['-background', options.background, '-flatten', '+matte']
if not options.size is None:
args += ['-filter', options.filter, '-resize', '%sx%s' % options.size]

if not options.type is None:
if options.type in img_type:
args += ['-type', options.type]
if not options.depth is None:
args += ['-depth', str(options.depth)]
elif options.type in img_cspace:
args += ['-colorspace', options.type]
if not options.depth is None:
args += ['-depth', str(options.depth)]

if pngout:
fd, tmpfile = mkstemp()
os_close(fd)
args.append('png:' + tmpfile)
Popen(args).communicate()
Popen(('pngcrush', '-rem', 'sRGB', tmpfile, output)).communicate()
remove(tmpfile)
else:
args.append(output)
Popen(args).communicate()
# END
else:
print >>stderr, 'No such file:', input
exit(2)
else:
parser.print_help()
exit(1)
% python flatten.py
Usage: flatten.py [ options ] input [ output ]

Options:
-h, --help show this help message and exit
-s SIZE, --size=SIZE The output size: WIDTHxHEIGHT
-n, --no-clobber The output size: WIDTHxHEIGHT
-f FILTER, --filter=FILTER
The filter to resize with if necessary.
-b BACKGROUND, --background=BACKGROUND
The background when flattening.
-F, --no-flatten Don't flatten the output.
-t TYPE, --type=TYPE The type of the output image: analogous to both -type
and -colorspace in ImageMagick
-d DEPTH, --depth=DEPTH
The depth of the output image.