ImagesPlus is an excellent but specialized program. It is more suited for processing of astronomical images than for general photography and is often used for sensor analysis using raw files. However, it is less suitable for general photography. Among other considerations, it does not appear to be color managed. It converts my D800e images into an untagged color space. ACR/LR (among others) is better suited for general photography. What about printing with profiles and softproofing?
Iris is another astronomical program favored by techies for analysis of raw files. It can split the CFA image into its channels (RGGB), perform mathematical operations, and perform demosaicing, WB and gamma corrections. It also does Richardson-Lucy deconvoluiton and VanClittret filtering. It also is not color managed. For general photography, I will stick to ACR/LR.
I suggest MATLAB. Most anything that can be done to a dataset in a usual programming language (such as c++, java and whatever photoshop is implemented in) can be done in MATLAB. The trade-off is that implementation effort is lower, while execution time is higher. There are specialized "toolboxes" for e.g. image processing. It even defaults to 64-bit float precision :-)
Calling dcraw (used as a proprietary raw format parser only, not for its development capabilities), I have setup simple development scripts using on the order of 50 lines of script code. Using only well-defined, mathematical vector-matrix operations.
fname = 'IMG_4311';
system(['./dcraw -v -i ', fname, '.CR2'])
system(['./dcraw -D -4 -T ', fname, '.CR2']);
im = double(imread([fname, '.tiff']));
im = im(1:2*floor(end/2), 1:2*floor(end/2)); %crop to even multiple of 2 for simplicity
im = im - 2^11;%remove bias
im = im ./ (2^14-2^11);%normalize
%% separate channels, naiive demosaicing
kernel1 = [1 2 1;...
2 4 2;...
1 2 1]./4;
kernel2 = [0 1 0;...
1 4 1;...
0 1 0]./4;
r = zeros(size(im));
r(1:2:end-1,1:2:end-1) = im(1:2:end-1,1:2:end-1);
r = conv2(r, kernel1, 'same');
g = zeros(size(im));
g(1:2:end-1,2:2:end ) = im(1:2:end-1,2:2:end );
g(2:2:end ,1:2:end-1) = im(2:2:end ,1:2:end-1);
g = conv2(g, kernel2, 'same');
b = zeros(size(im));
b(2:2:end ,2:2:end ) = im(2:2:end ,2:2:end );
b = conv2(b, kernel1, 'same');
%% white balance
white_patch = [1800 1200];%manually found "white patch"
r = r./r(white_patch(1), white_patch(2));
g = g./g(white_patch(1), white_patch(2));
b = b./b(white_patch(1), white_patch(2));
%% assembly and clipping
im2 = cat(3, r, g, b);
im2(im2<0) = 0;
im2(im2>1) = 1;
Results in the attached image. No part of my script is claimed to be "high quality" or even free of bugs. The sole purpose of my post is to show the relative ease of doing everything yourself if you are interested in the technical details.