Resizing multiple image files

For the Ponyo post I had a bunch of PNG 853×480 screenshots. At first, the post used 300×168 images, resized by the blog’s engine, such as the below one:

However, the ideal width for images in this blog is about 600 pixels:

For resizing multiple files I recurred to ImageMagick command line tools (here are some Windows Binary Releases). On Windows command prompt, it’s enough to type:

forfiles /M *.png /C “cmd /c convert -resize 70% @file resized_@file”

That way all of the images will have resized versions, at 70% their original size, yielding a 597-pixels width.

The Nightmare before Christmas

Improbable que unos días antes de Navidad se encuentre usted inmerso en los ajustes finales de un salvapantallas (protector de pantallas/screensaver). Su salvapantallas utiliza OpenGL para el renderizado, y corre en Windows. Flujos lógicos perfectamente sincronizados, compiladores felices, arte gráfico hermoso. Prueba A superada. Prueba B superada. El problema apareció en la prueba N. En específico, que su salvapantallas funcionó perfectamente en todas las máquinas, menos en aquella laptop con gráficos Intel. En esa máquina, triste e inexplicablemente, su salvapantallas no dispone de aceleración 3D. La máquina es capaz de aceleración 3D -mil veces comprobado-, y sin embargo, su lindo salvapantallas no puede aprovechar dicha aceleración. En esa laptop, su salvapantallas se ejecuta con una lentitud intolerable, parece un aborto en software. ¿Por qué todos los otros programas corren con aceleración 3D en esa laptop, pero su salvapantallas no? ¿Por qué? ¿Razones esotéricas? Después de todo, a nivel de ejecución, un salvapantallas es simplemente un ejecutable con extensión “scr” (obviemos, por innecesarios, los detalles sobre el procesamiento de la línea de comandos, el enlace con scrnsave.lib -si elige esa vía-, y algún otro escarmiento propio de los salvapantallas). Deseo que no pierda vitales minutos de su vida prisionero de dicha pesadilla. La razón -o sinrazón- del fiasco está aquí. Si observamos con cuidado, la única diferencia entre su salvapantallas y el resto de ejecutables que sí reciben aceleración 3D es la extensión del archivo. Alguien, en alguna parte del sistema, está detectando la extensión “scr” de nuestra aplicación y le niega la aceleración 3D. Bueno, cambie la extensión. En vez de “scr”, use “sCr” o algo así. Parece tonto -y lo es- pero funciona. De nada.

Retrieving system time: gettimeofday()

Some time ago, a friend of mine reported a problem with gettimeofday() under MinGW. It was a relatively common error: 'gettimeofday' undeclared (first use this function). Cause and solution of this problem is kind of easy, and we’ll present it at the end of the post. However, what’s that function gettimeofday()?

gettimeofday() is a function for retrieving system time in POSIX-compliant systems. Unlike the time() function, which has a resolution of 1 second, gettimeofday() has a higher resolution: microseconds. Specifically, the prototype of gettimeofday() is:

int gettimeofday (struct timeval *tp, struct timezone *tzp)

The function retrieves the current time expressed as seconds and microseconds since the Epoch, and stores it in the timeval structure pointed to by tp. The struct timeval has the following members:

long int tv_sec: Number of whole seconds of elapsed time.
long int tv_usec: The rest of the elapsed time (a fraction of a second), represented as the number of microseconds.

Thanks to the tv_usec member, we have a resolution of microseconds. It’s also important to remember what the Epoch is. The Epoch is just an arbitrary starting date set by the system in order to compute time, i.e., it’s a reference or base time. For instance, POSIX-compliant systems measure system time as the number of seconds elapsed since the start of the epoch at 1970-01-01 00:00:00 Z.

On its side, the struct timezone was used to return information about the time zone. However, using this parameter is obsolete (e.g., it has not been and will not be supported by libc or glibc). Therefore, tzp should be a null pointer, else the behavior may be unspecified (check your system’s specifications).

gettimeofday() returns 0 for success, or -1 for fail. Simple. Further, this function should be available in sys/time.h. But my friend’s installation of MinGW only included the following in sys/time.h:

#include <windows.h>

#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */
#define _TIMEVAL_DEFINED
struct timeval {
  long tv_sec;
  long tv_usec;
};
#define timerisset(tvp)	 ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
	(((tvp)->tv_sec != (uvp)->tv_sec) ? \
	((tvp)->tv_sec cmp (uvp)->tv_sec) : \
	((tvp)->tv_usec cmp (uvp)->tv_usec))
#define timerclear(tvp)	 (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif /* _TIMEVAL_DEFINED */

Continue reading “Retrieving system time: gettimeofday()”

coLinux, int 80 on Windows and other rants

Generally speaking, an Application Binary Interface (ABI) is the interface between an application program and the operating system. Conceptually, it’s related to the more well-known API concept. But ABIs are a low-level notion, while APIs are more leaned toward the application source code level.

Recently, a friend sent me an email exposing some problems he faced when trying to assemble on Cygwin a code originally targeted at Linux. The problem, as he stated, was that int 0x80 didn’t perform as expected. Well, plenty of explanations are pertinent:

Cygwin

Cygwin allows to run a collection of Unix tools on Windows, including the GNU development toolchain. However, at its core, cygwin is a library which translates the POSIX system call API into the pertinent Win32 system calls (system calls are often abbreviated as syscalls). Therefore, cygwin is a software layer between applications using POSIX system calls and the Win32 operating systems, which allows porting some Unix applications to Windows. This way you can, for instance, have the Apache daemon working as a Windows service. Other very attractive feature of Cygwin is its interactive environment: you can run your shell quite nicely, and run your Autoconf scripts, for example. However, porting means recompiling. There is no binary compatibility, and your program cannot run in computers without Cygwin (without CYGWIN1.DLL, more precisely). Furthermore, albeit some progress has been made, Cygwin is relatively slow (it’s a POSIX compatibility layer, after all.) If possible, I prefer to recompile my applications directly with MinGW. For me, this allows for a faster development cycle. Note, though, that Cygwin can compile MinGW-compatible executables. It’s just that, as aforesaid, I prefer to work with MinGW directly. I only work on Windows if I have to develop applications for Windows. But Linux’s development tools are the best, and we can access several of them by using MinGW. I think that Cygwin is best suited for general cross-development and for handling complicated software porting.

System Calls and int 0x80

A system call is a request by an active process for a service performed by the operating system kernel. Remember that a process is an executing (running) instance of a program, and the active process is the process currently using the CPU. The active process may perform a system call to request creation of other process, for instance. Or perhaps the process needs to communicate with a peripheral device. In Linux on x86, int 0x80 is the assembly language instruction that is used to invoke system calls. int 0x80 is a software interrupt, as it will be raised by a software process, not by hardware devices. Before invoking such interruption, our program has to store the system call number (which allows the operating system to know what service your program is specifically requesting ) in the proper register of the CPU. Every interrupt is a signal to the operating system, notifying it about the occurrence of an event that must be computationally handled.

Continue reading “coLinux, int 80 on Windows and other rants”