• mina86.com

  • Categories
  • Code
  • Contact
  • Calculating RGB↔XYZ matrix

    I’ve recently found myself in need of an RGB↔XYZ transformation matrix expressed to the maximum possible precision. Sources on the Internet typically limit the precision to a handful decimal places so I’ve performed do the calculations myself.

    What we’re looking for is a 3-by-3 matrix \(M\) which, when multiplied by red, green and blue coordinates of a colour, produces its XYZ coordinates. In other words, a change of basis matrix from a space whose basis vectors are RGB’s primary colours: $$ M = \begin{bmatrix} X_r & X_g & X_b \\ Y_r & Y_g & Y_b \\ Z_r & Z_g & Z_b \end{bmatrix} $$

    PSA: Yes, 64-byte key file is okay

    In an earlier entry I’ve changed generated key file used for disk encryption from 4096 to meagre 64 bytes. I gave no mention of that adjustment considering it unimportant but have since been enquired about security of such a short password.

    Rest assured, a 64-byte key file is sufficient for any symmetric encryption (disk encryption being one example) and anything more does not improve security.

    Go: string[]byte

    Yes… I’ve started coding in Go recently. It lacks many things but the one feature relevant to this post is const keyword. Arrays and slices in particular are always mutable and so equivalent of C’s const char * does not exist.

    On the other hand, strings are immutable which means that conversion between a string and []byte requires memory allocation and copying of the data1. Often this might be acceptable but to squeeze every last cycle the following two functions might help achieve zero-copy implementation:

    func String(bytes []byte) string {
    	hdr := *(*reflect.SliceHeader)(unsafe.Pointer(&bytes))
    	return *(*string)(unsafe.Pointer(&reflect.StringHeader{
    		Data: hdr.Data,
    		Len:  hdr.Len,
    	}))
    }
    
    func Bytes(str string) []byte {
    	hdr := *(*reflect.StringHeader)(unsafe.Pointer(&str))
    	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
    		Data: hdr.Data,
    		Len:  hdr.Len,
    		Cap:  hdr.Len,
    	}))
    }

    Depending on the length of the strings, the difference in performance might be noticeable:

    PSA: Creating world-unreadable files

    I’ve been reading tutorials on using key-files for disk encryption. Common approach for generating such files is to create it using something similar to head -c 4096 /dev/urandom >key-file and only then change it’s permissions (usually with a plain chmod 400 key-file) to prevent others from reading it.

    Please, stop doing this and spreading that method. The correct way of achieving the effect is:

    (umask 077; head -c 64 /dev/random >key-file)

    Or if the file needs to be created as root while command is run by a different user:

    sudo sh -c 'umask 077; head -c 64 /dev/random >key-file'

    The first method creates the file as world-readable1 and before its permission are changed anyone can read it. The second method creates the file as readable only by its owner from the beginning thus preventing the secret disclosure.

    Generating random reals

    A well known way of generating random floating-point numbers in the presence of a pseudo-random number generator (PRNG) is to divide output of the latter by one plus its maximum possible return value.

    extern uint64_t random_uint64(void);
    
    double random_double(void) {
    	return random_uint64() / (UINT64_MAX + 1.0);
    }

    This method is simple, effective, inefficient and wrong on a few levels.

    Python tips and tricks

    Python! My old nemesis, we meet again. Actually, we meet all the time, but despite that there are always things which I cannot quite remember how to do and need to look them up. To help with the searching, here there are collected in one post:

    Contiguous Memory Allocator resources

    Below is a list of materials about Contiguous Memory Allocator (CMA) and topics relating to it which may be of interest.

    Michał Nazarewicz and Marek Szyprowski. 2012. Continuous Memory Allocator, version 24.
    The final patchset that was merged in Linux 3.5.
    Michał Nazarewicz. 2013. Alokacja ciągłych fizycznie obszarów pamięci w systemie Linux. Bachelor’s thesis. WEiTI/ISE, PW, Warsaw.
    🇵🇱 Diploma thesis in Polish on the Continuous Memory Allocator.
    Michał Nazarewicz. 2012. A Deep Dive into CMA. Linux Weekly News (March 2012).
    A description of the way to integrate CMA with an architecture as well as short summary of how exactly CMA works.
    Michał Nazarewicz. 2012. Deep Dive into Contiguous Memory Allocator.
    A description of how to use and integrate CMA with an architecture. It is a first part of an extended version of the above LWN article and as such it includes much more details.
    Michał Nazarewicz. 2012. Contiguous Memory Allocator: Allocating Big Chunks of Physically Contiguous Memory. LinuxCon Europe, Barcelona, Spain.
    The presentation from the LinuxCon Europe (LCE) 2012 about CMA.
    Barry Song. 2012. A Simple Kernel Module as a Helper to Test CMA, vrsien 4.
    A short and simple driver that can be used to test CMA as well as see how it is used.
    Jonathan Corbet. 2011. A Reworked Contiguous Memory Allocator. Linux Weekly News (June 2011).
    An overwiev of the Contiguous Memory Allocator.
    Jonathan Corbet. 2011. CMA and ARM. Linux Weekly News (June 2011).
    An overview of the linear mapping problems CMA had on ARM platforms, and why the early fixups are required.
    Laura Abbott. 2012. Revoke LRU when trying to drop buffers.
    Patch which tries to improve CMA’s performance by removing buffer from LRU prior to migration. The thread also mentiones problem with ext4 not supporting migration of journal pages.
    Jonathan Corbet. 2010. Memory Compaction. Linux Weekly News (January 2010).
    An overview of Mel Gorman’s compaction patches. Compaction code is used by CMA for scanning for and migrating non-free pages.
    Jonathan Corbet. 2009. Transcendent memory. Linux Weekly News (July 2009).
    Overwiev of an idea behind and implementation of the transcendent memory. Such memory can be marked ‘ephemeral’ which means that kernel can discard it if it wishes to.
    Jonathan Corbet. 2011. POSIX_FADV_VOLATILE. Linux Weekly News (November 2011).
    An overwiev of John Stultz’s POSIX_FADV_VOLATILE implementation which is one of the things that CMA work with nicely.
    Minchan Kim. 2012. Discard clean pages during contiguous allocation instead of migration.
    Patch changing CMA so that clean pages are discarded instead of migrating which improves CMA’s performance.

    On Unicode

    There are a lot of misconceptions about Unicode. Most are there because people assume what they know about ASCII or ISO-8859-* is true about Unicode. They are usually harmless but they tend to creep into minds of people who work with text which leads to badly designed software and technical decisions made based on false information.

    Without further ado, here’s a few facts about Unicode that might surprise you.

    Bash right prompt

    There are multiple ways to customise Bash prompt. There’s no need to look for long to find plethora of examples with fancy, colourful PS1s. What have been a bit problematic is having text on the right of the input line. In this article I’ll try to address that shortcoming.

    Getting text on the right

    The typical approach is using PROMPT_COMMAND to output desired content. The variable specifies a shell code Bash executes prior to rendering the primary prompt (i.e. PS1).

    The idea is to align text to the right and then using carrier return move the cursor back to the beginning of the line where Bash will start rendering its prompt. Let’s look at an example of showing time in various locations:

    __command_rprompt() {
    	local times= n=$COLUMNS tz
    	for tz in ZRH:Europe/Zurich PIT:US/Eastern \
    	          MTV:US/Pacific TOK:Asia/Tokyo; do
    		[ $n -gt 40 ] || break
    		times="$times ${tz%%:*}\e[30;1m:\e[0;36;1m"
    		times="$times$(TZ=${tz#*:} date +%H:%M)\e[0m"
    		n=$(( $n - 10 ))
    	done
    	[ -z "$times" ] || printf "%${n}s$times\\r" ''
    }
    PROMPT_COMMAND=__command_rprompt
    Terminal window presenting right prompt behaviour.

    Clearing the line on execution

    It has one annoying issue. The right text reminds on screen even after executing a command. Typically this is a matter of aesthetic but it also makes copying and pasting session history more convoluted.

    A manual solution is to use redraw-current-line readline function (e.g. often bound to C-l). It clears the line and prints the prompt and whatever input has been entered thus far. PROMPT_COMMAND is not executed so the right text does not reappear.

    Lack of automation can be addressed with a tiny bit of readline magic and a ~/.inputrc file which deserves much more fame than what it usually gets.

    Tricky part is bindind C-m and C-j to two readline functions, redraw-current-line followed by accept-line, which is normally not possible. This limitation can be overcome by binding the key sequences to a different sequence which will be interpreted recursively.

    To test that idea it’s enough to execute:

    bind '\C-l:redraw-current-line'
    bind '\M-\C-j:accept-line'
    bind '\C-j:"\C-l\M-\C-j"' '\C-m:"\C-j"'

    Making this permanent is as easy as adding the following lines to ~/.inputrc:

    $if Bash
        "\C-l": redraw-current-line
        "\e\C-j": accept-line
        "\C-j": "\C-l\e\C-j"
        "\C-m": "\C-l\e\C-j"
    $endif

    With that, the right prompt will disappear as soon as the shell command is executed. (Note the use of \M- in bind command vs. \e in ~/.inputrc file).

    Mobile is the future

    Photo of a smashed mobile phone.
    (photo by Cory Doctorow)

    A few days ago I received an email from Google Wembaster Tools saying no more no less but: ‘Your webpage sucks on mobile devices!’ Or something. Now that I think of it, I could have been worded slightly differently. The gist was the same though.

    I never paid that much attention to how my site looks on phones and tables. I’ve made sure it loaded and looked, but apart from that never spent much time on the issue. I always thought optimising for a small screen would be a lengthy and painful process. How mistaken I was!

    In my defence, when I last looked at the problem, state of mobile browsers was different; now there are two things to do. First, add a viewport meta tag, e.g.:

    <meta name=viewport
          content="width=device-width, initial-scale=1">

    and then use min-width or max-width CSS media queries. Admittedly the second part may take some time, but if your layout uses simple markup rather than being TABLE-based, reading the excellent article on A List Apart might turn out to be the most time consuming step.

    If you haven’t already, do take a look at whether your website looks reasonably well on small screens. Apparently mobile is the future, or some such.

    The ‘bad’ news is that I’ve dropped endless scroll feature. This is because in narrow layout the sidebar moves to the bottom and endless scrolling would make it unreachable since it would run away all the time.