Roland's homepage

My random knot in the Web

Patching CalculiX Graphics to fix flipped screen hardcopy

Since some time, I’ve had the problem that generating hardcopy images from cgx doesn’t work properly; the pictures are inverted vertically.

At first, I thought this might have been a change in cgx. But comparing the source code for cgx.c for 2.16 up to and including 2.19, I don’t see anything that would explain it.

The image that cgx generates consists out of multiple parts that are saved as intermediate tga (targa) files. The composite program from ImageMagick is that used to combine them into a single tga-file. Converting that single tga file to other formats is the job of the convert program (also from ImageMagick).

When I made a small change to cgx to not delete the intermediate tga-files, I noticed that I could view those just fine. It was only after I tried to use convert to change them into say png files that I noted that they ware inverted. This makes it into an ImageMagick problem.

After a day of searching and experimenting, I found this ImageMagick issue. According to the ImageMagick developers, this behavior is expected, and you should always use the -auto-orient option when converting a tga-file. Personally, I find the reasoning behind that somewhat bizarre, especially since it used to work withouth this option. But it is what it is.

Since composite does not support the -auto-orient option, I created a patch for cgx. This adds some mogrify calls to fix the orientation for the intermediate files.

It also adds -auto-orient options to all the convert calls just to be sure, although that last bit might be overdoing it.

--- cgx.c.orig      2022-02-27 01:13:45.360230000 +0100
+++ cgx.c   2022-02-27 14:20:13.251444000 +0100
@@ -856,14 +856,24 @@
    while( access( "0__.tga", F_OK ) != 0 );
    while( access( "1__.tga", F_OK ) != 0 );
    while( access( "2__.tga", F_OK ) != 0 );
-    //sprintf( buffer, "composite -compose atop -gravity SouthWest -geometry +1+1 2__.tga 1__.tga 3__.tga");
+    sprintf(buffer, "mogrify -auto-orient 0__.tga");
+    system(buffer);
+    sprintf(buffer, "mogrify -auto-orient 1__.tga");
+    system(buffer);
+    sprintf(buffer, "mogrify -auto-orient 2__.tga");
+    system(buffer);
+
    sprintf( buffer, "composite -gravity SouthWest -geometry +1+1 2__.tga 1__.tga 3__.tga");
    system (buffer);
    while( access( "3__.tga", F_OK ) != 0 );
+    sprintf(buffer, "mogrify -auto-orient 3__.tga");
+    system(buffer);
    //sprintf( buffer, "composite -compose atop -gravity NorthWest -geometry +%d+%d 3__.tga 0__.tga hcpy_%d.tga",
    sprintf( buffer, "composite -alpha off -gravity NorthWest -geometry +%d+%d 3__.tga 0__.tga hcpy_%d.tga",
        (GLint)width_menu*19/20, (GLint)height_menu/10, nr);
    system (buffer);
+    sprintf(buffer, "mogrify -auto-orient hcpy_%d.tga", nr);
+    system(buffer);
    //printf("%s",buffer);
    sprintf( buffer, "rm -f *__.tga %s",DEV_NULL);
    system (buffer);
@@ -908,7 +918,7 @@
    getTGAScreenShot(psNr);
    /* on some systems PS has to be changed to PS2 */
    //sprintf( buffer, "convert -density %dx%d -page +49+196 -gamma %lf hcpy_%d.tga PS:hcpy_%d.ps   ", (int)((double)(PS_DENSITY*width_w0)/(double)(INI_SCREEN+INI_MENU_WIDTH)),(int)((double)(PS_DENSITY*width_w0)/(double)(INI_SCREEN+INI_MENU_WIDTH)) , GAMMA, psNr, psNr);
-      sprintf( buffer, "convert hcpy_%d.tga -page A4 %s", psNr, fileName);
+      sprintf( buffer, "convert hcpy_%d.tga -auto-orient -page A4 %s", psNr, fileName);
    system (buffer);
    printf("%s\n", buffer);
    sprintf( buffer, "rm -f hcpy_%d.tga %s",psNr,DEV_NULL);
@@ -941,7 +951,7 @@
    getTGAScreenShot(0);
    while( access( "hcpy_0.tga", F_OK ) != 0 );
    gifNr++;
-      sprintf( buffer, "convert hcpy_0.tga _%d.gif",gifNr);
+      sprintf( buffer, "convert hcpy_0.tga -auto-orient _%d.gif",gifNr);
    printf("%s\n",buffer);
    system (buffer);
    if((movieFrames)&&(gifNr>=movieFrames))
@@ -965,7 +975,7 @@
    if(filePtr!=NULL) sprintf(fileName,"%s.gif",filePtr); else sprintf(fileName,"hcpy_%d.gif",gifNr);
    printf("create %s\n ",fileName);
    getTGAScreenShot(gifNr);
-      sprintf( buffer, "convert hcpy_%d.tga %s", gifNr, fileName);
+      sprintf( buffer, "convert hcpy_%d.tga -auto-orient %s", gifNr, fileName);
    system (buffer);
    sprintf( buffer, "rm -f hcpy_%d.tga %s",gifNr,DEV_NULL);
    system (buffer);
@@ -980,7 +990,7 @@
    if(filePtr!=NULL) sprintf(fileName,"%s.png",filePtr); else sprintf(fileName,"hcpy_%d.png",pngNr);
    printf("create %s\n ",fileName);
    getTGAScreenShot(pngNr);
-      sprintf( buffer, "convert hcpy_%d.tga %s", pngNr, fileName);
+      sprintf( buffer, "convert hcpy_%d.tga -auto-orient %s", pngNr, fileName);
    system (buffer);
    sprintf( buffer, "rm -f hcpy_%d.tga %s",pngNr,DEV_NULL);
    system (buffer);

For comments, please send me an e-mail.


Related articles


←  Does repeated JPEG conversion reduce quality? No AI training data here  →