Subversion Repositories filter_foundry

Rev

Rev 537 | Rev 541 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
  3.     Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.net
  4.     Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. */
  20.  
  21. #include "ff.h"
  22.  
  23. #include "version.h"
  24. #include "time.h"
  25. #include "file_compat.h"
  26. #include "sprintf_tiny.h"
  27.  
  28. #define CHOPLINES 63
  29.  
  30. OSErr putstr(Handle h,char *s);
  31.  
  32. OSErr putstr(Handle h,char *s){
  33.         Ptr p;
  34.         OSErr e;
  35.         size_t size, n;
  36.  
  37.         if (!h) return nilHandleErr;
  38.  
  39.         size = PIGETHANDLESIZE(h);
  40.         n = strlen(s);
  41.  
  42.         if(!(e = PISETHANDLESIZE(h,(int32)(size+n)))){
  43.                 p = PILOCKHANDLE(h,false);
  44.                 memcpy(p+size,s,n);
  45.                 PIUNLOCKHANDLE(h);
  46.         }
  47.         return e;
  48. }
  49.  
  50. OSErr saveparams_afs_pff(Handle h){
  51.         char outbuf[CHOPLINES * 2 + 2] = "";
  52.         char *q, * p, * r, * start;
  53.         size_t n, chunk, j;
  54.         int i;
  55.         OSErr e;
  56.         size_t est;
  57.         static char afs_sig[] = "%RGB-1.0\r";
  58.  
  59.         if (!h) return nilHandleErr;
  60.  
  61.         est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
  62.         // do not be tempted to combine into one expression: 'est' is referenced below
  63.         est += strlen(afs_sig) + est/CHOPLINES + 4 + 8*6 + 64 /*slop*/ ;
  64.  
  65.         PIUNLOCKHANDLE(h); // should not be necessary
  66.         if( !(e = PISETHANDLESIZE(h,(int32)(est))) && (p = start = PILOCKHANDLE(h,false)) ){
  67.                 // build one long string in AFS format
  68.                 p = cat(p,afs_sig); // first the header signature
  69.  
  70.                 /* then slider values, one per line */
  71.                 for( i=0 ; i<8 ; ++i )
  72.                         p += sprintf(p, "%d\r", slider[i]);
  73.  
  74.                 /* expressions, broken into lines no longer than CHOPLINES characters */
  75.                 for( i=0 ; i<4 ; ++i ){
  76.                         if ((r = expr[i])) {
  77.                                 chunk = 0; // to avoid that compiler complains
  78.                                 for (n = strlen(r); n; n -= chunk) {
  79.                                         chunk = n > (int)CHOPLINES ? (int)CHOPLINES : n;
  80.                                         for (j = chunk, q = outbuf; j--; )
  81.                                                 if (*r == CR) {
  82.                                                         *q++ = '\\';
  83.                                                         *q++ = 'r';
  84.                                                         ++r;
  85.                                                 }
  86.                                                 else if (*r == LF) {
  87.  
  88.                                                         // This can only happen with Windows or Linux.
  89.                                                         // Native Linux is not supported, and Windows always combines LF with CR. So we can ignore LF.
  90.                                                         ++r;
  91.                                                 }
  92.                                                 else
  93.                                                         *q++ = *r++;
  94.                                         *q++ = CR;
  95.                                         *q = 0;
  96.                                         p = cat(p, outbuf);
  97.                                 }
  98.                         }
  99.                         else
  100.                                 p = cat(p,(char*)("(null expr)\r")); // this shouldn't happen
  101.                         *p++ = CR;
  102.                 }
  103.  
  104. //              *p = 0; dbg(start);
  105.  
  106.                 PIUNLOCKHANDLE(h);
  107.                 e = PISETHANDLESIZE(h,(int32)(p - start)); // could ignore this error, maybe
  108.         }
  109.  
  110.         return e;
  111. }
  112.  
  113. OSErr saveparams_picotxt(Handle h, Boolean useparm) {
  114.         extern int ctls[], maps[];
  115.  
  116.         char * p, *start;
  117.         int i;
  118.         OSErr e;
  119.         size_t est;
  120.  
  121.         if (!h) return nilHandleErr;
  122.  
  123.         est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
  124.         // do not be tempted to combine into one expression: 'est' is referenced below
  125.         est += 16000;
  126.  
  127.         PIUNLOCKHANDLE(h); // should not be necessary
  128.         if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
  129.                 checksliders(4, ctls, maps);
  130.  
  131.                 // Metadata
  132.                 p += sprintf(p, "Category: %s\r\n", useparm ? gdata->parm.szCategory : "...");
  133.                 p += sprintf(p, "Title: %s\r\n", useparm ? gdata->parm.szTitle : "...");
  134.                 p += sprintf(p, "Copyright: %s\r\n", useparm ? gdata->parm.szCopyright : "...");
  135.                 p += sprintf(p, "Author: %s\r\n", useparm ? gdata->parm.szAuthor : "...");
  136.                 p += sprintf(p, "Filename: %s\r\n", useparm ? "Untitled.8bf" : "Untitled.8bf"); // TODO: get .txt filename and change .txt to .8bf
  137.                 p += sprintf(p, "\r\n");
  138.                 p += sprintf(p, "R: %s\r\n", useparm ? gdata->parm.szFormula[0] : expr[0]);
  139.                 p += sprintf(p, "\r\n");
  140.                 p += sprintf(p, "G: %s\r\n", useparm ? gdata->parm.szFormula[1] : expr[1]);
  141.                 p += sprintf(p, "\r\n");
  142.                 p += sprintf(p, "B: %s\r\n", useparm ? gdata->parm.szFormula[2] : expr[2]);
  143.                 p += sprintf(p, "\r\n");
  144.                 p += sprintf(p, "A: %s\r\n", useparm ? gdata->parm.szFormula[3] : expr[3]);
  145.                 p += sprintf(p, "\r\n");
  146.                 if (useparm) {
  147.                         for (i = 0; i < 8; i++) {
  148.                                 if (gdata->parm.ctl_used[i]) {
  149.                                         p += sprintf(p, "ctl[%d]: %s\r\n", i, gdata->parm.szCtl[i]);
  150.                                 }
  151.                         }
  152.                         for (i = 0; i < 4; i++) {
  153.                                 if (gdata->parm.map_used[i]) {
  154.                                         p += sprintf(p, "map[%d]: %s\r\n", i, gdata->parm.szMap[i]);
  155.                                 }
  156.                         }
  157.                         p += sprintf(p, "\r\n");
  158.                         for (i = 0; i < 8; i++) {
  159.                                 if (gdata->parm.ctl_used[i]) {
  160.                                         p += sprintf(p, "val[%d]: %d\r\n", i, gdata->parm.val[i]);
  161.                                 }
  162.                         }
  163.                         /*
  164.                         p += sprintf(p, "\r\n");
  165.                         for (i = 0; i < 8; i++) {
  166.                                 if (gdata->parm.ctl_used[i]) {
  167.                                         p += sprintf(p, "def[%d]: %d\r\n", i, gdata->parm.val[i]);
  168.                                 }
  169.                         }
  170.                         */
  171.                 }
  172.                 else {
  173.                         for (i = 0; i < 8; i++) {
  174.                                 if (ctls[i]) {
  175.                                         p += sprintf(p, "ctl[%d]: %s\r\n", i, "...");
  176.                                 }
  177.                         }
  178.                         for (i = 0; i < 4; i++) {
  179.                                 if (maps[i]) {
  180.                                         p += sprintf(p, "map[%d]: %s\r\n", i, "...");
  181.                                 }
  182.                         }
  183.                         p += sprintf(p, "\r\n");
  184.                         for (i = 0; i < 8; i++) {
  185.                                 if (ctls[i]) {
  186.                                         p += sprintf(p, "val[%d]: %d\r\n", i, slider[i]);
  187.                                 }
  188.                         }
  189.                         /*
  190.                         p += sprintf(p, "\r\n");
  191.                         for (i = 0; i < 8; i++) {
  192.                                 if (ctls[i]) {
  193.                                         p += sprintf(p, "def[%d]: %s\r\n", i, "...");
  194.                                 }
  195.                         }
  196.                         */
  197.                 }
  198.  
  199.                 PIUNLOCKHANDLE(h);
  200.                 e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
  201.         }
  202.  
  203.         return e;
  204. }
  205.  
  206. OSErr saveparams_guf(Handle h, Boolean useparm) {
  207.         extern int ctls[], maps[];
  208.  
  209.         char* p, * start;
  210.         int i;
  211.         OSErr e;
  212.         size_t est;
  213.  
  214.         if (!h) return nilHandleErr;
  215.  
  216.         est = strlen(expr[0]) + strlen(expr[1]) + strlen(expr[2]) + strlen(expr[3]);
  217.         // do not be tempted to combine into one expression: 'est' is referenced below
  218.         est += 16000;
  219.  
  220.         // TODO: Encode the file in UTF-8! (German Umlauts, etc.)
  221.  
  222.         PIUNLOCKHANDLE(h); // should not be necessary
  223.         if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
  224.                 char strBuildDate[11/*strlen("0000-00-00") + 1*/];
  225.                 time_t iBuildDate = time(0);
  226.                 strftime(strBuildDate, 100, "%Y-%m-%d", localtime(&iBuildDate));
  227.  
  228.                 checksliders(4, ctls, maps);
  229.  
  230.                 // Metadata
  231.                 p += sprintf(p, "# Created with Filter Foundry %s\r\n", VERSION_STR);
  232.                 p += sprintf(p, "\r\n");
  233.                 p += sprintf(p, "[GUF]\r\n");
  234.                 p += sprintf(p, "Protocol=1\r\n");
  235.                 p += sprintf(p, "\r\n");
  236.                 p += sprintf(p, "[Info]\r\n");
  237.                 p += sprintf(p, "Category=<Image>/Filter Factory/%s\r\n", useparm ? gdata->parm.szCategory : "...");
  238.                 p += sprintf(p, "Title=%s\r\n", useparm ? gdata->parm.szTitle : "...");
  239.                 p += sprintf(p, "Copyright=%s\r\n", useparm ? gdata->parm.szCopyright : "...");
  240.                 p += sprintf(p, "Author=%s\r\n", useparm ? gdata->parm.szAuthor : "...");
  241.                 p += sprintf(p, "\r\n");
  242.                 p += sprintf(p, "[Version]\r\n");
  243.                 p += sprintf(p, "Major=1\r\n");
  244.                 p += sprintf(p, "Minor=0\r\n");
  245.                 p += sprintf(p, "Micro=0\r\n");
  246.                 p += sprintf(p, "\r\n");
  247.                 p += sprintf(p, "[Filter Factory]\r\n");
  248.                 p += sprintf(p, "8bf=%s\r\n", useparm ? "Untitled.8bf" : "Untitled.8bf"); // TODO: get .guf filename and change .guf to .8bf
  249.                 p += sprintf(p, "\r\n");
  250.                 p += sprintf(p, "[Gimp]\r\n");
  251.                 p += sprintf(p, "Registered=false\r\n");
  252.                 p += sprintf(p, "Description=%s\r\n", useparm ? gdata->parm.szTitle : "...");
  253.                 p += sprintf(p, "EdgeMode=2\r\n");
  254.                 p += sprintf(p, "Date=%s\r\n", strBuildDate);
  255.                 p += sprintf(p, "\r\n");
  256.  
  257.                 if (useparm) {
  258.                         for (i = 0; i < 8; i++) {
  259.                                 p += sprintf(p, "[Control %d]\r\n", i);
  260.                                 p += sprintf(p, "Enabled=%s\r\n", gdata->parm.ctl_used[i] ? "true" : "false");
  261.                                 p += sprintf(p, "Label=%s\r\n", gdata->parm.szCtl[i]);
  262.                                 p += sprintf(p, "Preset=%d\r\n", gdata->parm.val[i]);
  263.                                 p += sprintf(p, "Step=1\r\n");
  264.                                 p += sprintf(p, "\r\n");
  265.                         }
  266.                         for (i = 0; i < 4; i++) {
  267.                                 p += sprintf(p, "[Map %d]\r\n", i);
  268.                                 p += sprintf(p, "Enabled=%s\r\n", gdata->parm.map_used[i] ? "true" : "false");
  269.                                 p += sprintf(p, "Label=%s\r\n", gdata->parm.szMap[i]);
  270.                                 p += sprintf(p, "\r\n");
  271.                         }
  272.                 }
  273.                 else {
  274.                         for (i = 0; i < 8; i++) {
  275.                                 p += sprintf(p, "[Control %d]\r\n", i);
  276.                                 p += sprintf(p, "Enabled=%s\r\n", ctls[i] ? "true" : "false");
  277.                                 p += sprintf(p, "Label=%s\r\n", "...");
  278.                                 p += sprintf(p, "Preset=%d\r\n", slider[i]);
  279.                                 p += sprintf(p, "Step=1\r\n");
  280.                                 p += sprintf(p, "\r\n");
  281.                         }
  282.                         for (i = 0; i < 4; i++) {
  283.                                 p += sprintf(p, "[Map %d]\r\n", i);
  284.                                 p += sprintf(p, "Enabled=%s\r\n", maps[i] ? "true" : "false");
  285.                                 p += sprintf(p, "Label=%s\r\n", "...");
  286.                                 p += sprintf(p, "\r\n");
  287.                         }
  288.                 }
  289.        
  290.                 p += sprintf(p, "[Code]\r\n");
  291.                 p += sprintf(p, "R=%s\r\n", useparm ? gdata->parm.szFormula[0] : expr[0]);
  292.                 p += sprintf(p, "G=%s\r\n", useparm ? gdata->parm.szFormula[1] : expr[1]);
  293.                 p += sprintf(p, "B=%s\r\n", useparm ? gdata->parm.szFormula[2] : expr[2]);
  294.                 p += sprintf(p, "A=%s\r\n", useparm ? gdata->parm.szFormula[3] : expr[3]);
  295.  
  296.                 PIUNLOCKHANDLE(h);
  297.                 e = PISETHANDLESIZE(h, (int32)(p - start)); // could ignore this error, maybe
  298.         }
  299.  
  300.         return e;
  301. }
  302.  
  303. OSErr savehandleintofile(Handle h,FILEREF r){
  304.         Ptr p;
  305.         FILECOUNT n;
  306.         OSErr e;
  307.  
  308.         if (!h) return nilHandleErr;
  309.         p = PILOCKHANDLE(h,false);
  310.         n = (FILECOUNT)PIGETHANDLESIZE(h);
  311.         e = FSWrite(r,&n,p);
  312.         PIUNLOCKHANDLE(h);
  313.         return e;
  314. }
  315.  
  316. Boolean savefile_afs_pff_picotxt_guf(StandardFileReply *sfr){
  317.         FILEREF r;
  318.         Handle h;
  319.         Boolean res = false;
  320.         TCHAR* reasonstr = NULL;
  321.  
  322.         FSpDelete(&sfr->sfFile);
  323.         if(FSpCreate(&sfr->sfFile,SIG_SIMPLETEXT,TEXT_FILETYPE,sfr->sfScript) == noErr)
  324.                 if(FSpOpenDF(&sfr->sfFile,fsWrPerm,&r) == noErr){
  325.  
  326.                         if (fileHasExtension(sfr, TEXT(".txt"))) {
  327.                                 // PluginCommander .txt
  328.                                 if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
  329.                                         res = !(saveparams_picotxt(h, false) || savehandleintofile(h, r));
  330.                                         PIDISPOSEHANDLE(h);
  331.                                 }
  332.                         }
  333.  
  334.                         if (fileHasExtension(sfr, TEXT(".guf"))) {
  335.                                 // GIMP UserFilter file
  336.                                 if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
  337.                                         res = !(saveparams_guf(h, false) || savehandleintofile(h, r));
  338.                                         PIDISPOSEHANDLE(h);
  339.                                 }
  340.                         }
  341.  
  342.                         if ((fileHasExtension(sfr, TEXT(".afs"))) || (fileHasExtension(sfr, TEXT(".pff")))) {
  343.                                 if (fileHasExtension(sfr, TEXT(".pff"))) {
  344.                                         // If it is a Premiere settings file, we need to swap the channels red and blue
  345.                                         // We just swap the pointers!
  346.                                         char* tmp;
  347.                                         tmp = expr[0];
  348.                                         expr[0] = expr[2];
  349.                                         expr[2] = tmp;
  350.                                 }
  351.  
  352.                                 if ((h = PINEWHANDLE(1))) { // don't set initial size to 0, since some hosts (e.g. GIMP/PSPI) are incompatible with that.
  353.                                         res = !(saveparams_afs_pff(h) || savehandleintofile(h, r));
  354.                                         PIDISPOSEHANDLE(h);
  355.                                 }
  356.  
  357.                                 if (fileHasExtension(sfr, TEXT(".pff"))) {
  358.                                         // Swap back so that the other program stuff will work normally again
  359.                                         char* tmp;
  360.                                         tmp = expr[0];
  361.                                         expr[0] = expr[2];
  362.                                         expr[2] = tmp;
  363.                                 }
  364.                         }
  365.  
  366.                         FSClose(r);
  367.                 }else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_OPEN_FILE_ID);
  368.         else reasonstr = FF_GetMsg_Cpy(MSG_CANNOT_CREATE_FILE_ID);
  369.  
  370.         if (!res) {
  371.                 alertuser_id(MSG_CANNOT_SAVE_SETTINGS_ID, reasonstr);
  372.         }
  373.  
  374.         if (reasonstr) FF_GetMsg_Free(reasonstr);
  375.  
  376.         return res;
  377. }
  378.