Scaling images with alpha blending properly with PHP gd

I had some code trying to scale an image in gd using the imagescale function, that looked something like this:

/* makes a copy of the image, instead of modifying in place */
$target = imagescale($image, $width, $height);

However, the images it created were heavily distorted when using bilinear filtering, and didn’t quite look right with neared neighbour either. For example, with bilinear filtering…

Continue reading

Portable software is more complex than you think

I’m someone who cares about making software portable. In fact, I actually have a job basically doing so. For most Unix-shaped things (better known as things, since Unix destroyed all competition), the POSIX standard exists to codify common attributes and provide a common ground. Unfortunately, this is made far more complicated by systems both doing many things outside of POSIX’s lowest common denominator, and systems just not implementing POSIX correctly. People tend to think “portability” is whatever operating systems they use, and assuming the lowest common denominator is that. While many guides recommend writing software in a disciplined (or tortured, if you disagree) manner with separate compilation units for platform differences when possible, the reality is your codebase will have #ifdefs and a configure script if it does anything useful. Not to mention the increasing irrelevance of the standard itself.

Continue reading

Quick and dirty subclassing in Win32

Context: So I wanted to implement drag and drop with files the quick and dirty way; specifically, WM_DROPFILES. (You can also do this with COM, but it’s a bit more involved, especially from raw C. I haven’t written about drag and drop yet, so the comparison is covered elsewhere for now.) My use case is simple, so I didn’t need the benefits or complexity of COM drag and drop. Turns out it’s just marking it as having the extended style in the resource editor or calling DragAcceptFiles, or so I thought. While I could get my dialog to accept the files, I couldn’t get the list view to do so. It turns out that the list view doesn’t handle these messages, nor does it send a notification back to the parent.

One strategy to deal with this is subclassing, although we aren’t going through the formal channels to do. That’s trickier, because it involves using things like CreateWindowEx, and might be a pain with dialog resources that already have a list view. Instead, we’ll actually replace the window procedure out from under the already materialized dialog control – basically monkey patching. In fact, Microsoft’s own documentation mentions this (and a better way with caveats). However, it doesn’t provide a concrete example. This article will quickly show you how, and provides an interesting, if brief example of Windows API principles.

Continue reading

Notes on the system image list

If you need the icons for files in a Windows program, the easiest way to do so is with the system image list. This is an image list (a resource containing icons, mapped by index) that caches those system icons. The advantage of being an image list is you can easily associate it with a control (like a ListView) and pick out the images by their index, or draw out of it.

Continue reading

UTF-8 conversion issues on legacy Windows

Short post: On Windows, UTF-16 was the dominant locale, and UTF-8 was something only to convert to and from. (Microsoft jumped the gun before Unicode expanded the address space.) While it got better (Windows 10 can use UTF-8 as an MBCS locale with ANSI APIs), it was historically a lot worse.

For converting, you’d use the MultiByteToWideChar and its opposite WideCharToMultiByte. On legacy Windows, they have slightly confusing semantics. Specifically, with flags. While Vista on introduced many flags that can be used with the UTF-8 codepage (to deal with the quirks of conversion, like invalid characters), previously only MB_ERR_INVALID_CHARS was allowed, and only if you were running XP or 2000 SP4. Before that, you can’t have any flags if you’re converting to or from UTF-16 and UTF-8. It’s unfortunately a little dangerous, but that’s the rub.

It never had to be like this: the git “index”

Hot on the heels of another Git-related article that was making the rounds recently, I was reminded of Git’s own structure and how it influences user experience. Specifically what we assume is part of how Git works, is actually a part of the porcelain (in Git speak, the user interface and commands that back it). As someone developing a Git client, it’s interesting to think Git’s user experience could be significantly different with a different interface, particularly because people have a particular mental model of Git influenced by the default interface. Said influence is enough that libgit2’s API emulates the porcelain’s semantics, in-process.

Continue reading

Couldn’t create window class error with a simple dialog-based Win32 application

I had a simple Win32 application fail to create its window (in my case, a dialog box, using either CreateDialog or DialogBox). I got back the error 0x583; unable to create window class. If I forced the window style on my dialog to create regardless of errors, my dialog was empty.

It turns out I was using themed controls in my manifest, but I didn’t call InitCommonControls. After that, my application worked.

There is no 64-bit type in C89

Brief post, but I was porting a C89 project to Visual C++ 6 (don’t ask) when I found something really fun. Turns out “long long“, the type everyone assumes is the 64-bit type in C, is actually a GCC extension. MSVC uses… _int64, a different extension. Great, had to convert a bunch of code. You’ll get this fun error from old MSVC when it sees it:

error C2632: 'long' followed by 'long' is illegal

(Note that MSVC will probably assume your C code is C++, which does mean you get some stuff from C99 for free like single-line comments… but then initializers are different between C and C++, and C++ only added long long in C++11…)

It’s an unfortunate gotcha for those who assume they’re writing standards compliant C89. The reason might be deflated when you have to define your own 64-bit integer with #ifdef. Oh, and let’s not forgot “long long” could mean 72-bit on your 9-bit byte system, of course. That’s why stdint.h exists…. except, oh, C89.

Compilation tags and you

I’m trying out Navidrome, a lightweight alternative to Airsonic, and I had difficulty with my music seemingly being tagged various artists when it shouldn’t (sometimes with different tracks), and albums with various artists being considered separate albums. Obviously, this is pretty annoying since I haven’t seen other music library software do it.

Continue reading