Q:

How to make the viewport of an SVG image square, without resizing its contents?

I have an SVG image (lets say a simple icon) which has following content:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/></svg>

The viewbox is not square (448!=512) I need to make the shorter edge equal to the longer one, in a way that its content does not loose their original ratio (=> don't stretch), and they need to get at the exact center of the canvas.
Example: Convert image on the left to the one on the right. (borders are not actual path but viewbox)
 
Programming languages and tools does not matter. I just need something that I can apply to many files (in a bash script). So imagemagick, inkscape, python with thirdparty libs solutions are welcome.

A:

Playing with your test svg (using internet explorer as viewer) reveals that changing viewBox for SVG without defined width,height does not change their aspect (no stretching just zoom and pan) so no need to use matrices all can be done in viewBox alone. Here your example:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
 <path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/>
</svg>

so you want to change 448 to 512 but we want to still make the image centered so we need to adjust the x0 position too (in opposite direction by half of difference (512-448)/2 = 32). So change the viewBox to:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 0 512 512">
 <path d="M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zm-74 304H54a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v404a6 6 0 0 1-6 6zM128 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm208 133.477V360c0 13.255-10.745 24-24 24H104c-13.255 0-24-10.745-24-24v-18.523c0-22.026 14.99-41.225 36.358-46.567l35.657-8.914c29.101 20.932 74.509 26.945 111.97 0l35.657 8.914C321.01 300.252 336 319.452 336 341.477z"/>
</svg>

so let assume original parameters are: viewBox(x0,y0,xs0,ys0) then the new ones would be viewBox(x1,y1,xs1,ys1) where:
xs1= ys1 = max(xs0,ys0);
x1 = x0 + (xs0 - xs1)/2;
y1 = y0 + (ys0 - ys1)/2;

As SVG is just text file (XML) in case you do not have R/W access to SVG::viewBox in your environment then just write a script that search/parse/replace viewBox text in text file ... I do not code in python but in C++ would be just "few" lines of code (beware some SVG's are ASCII some are UNICODE).

