csh file structure?

Discussion of the xtools Toolkit

Moderators: Tom, Kukurykus

Mike Hale

csh file structure?

Post by Mike Hale »

I need to get the exact aspect ratio of the path used to create a custom shape from the csh file. I tried using shapeInfo from xtools but I am getting inconsistent results. Some time the shape height and width matches the path at created the path and some times one or both both dimensions are off.

X, when you were working on shapeFile.js did you work out the csh file structure well enough to get the path point info from the file?

I can find where the number of path points for the shape is stored and where the data for those path points are but I am having trouble working out how to extract the path points.
xbytor

csh file structure?

Post by xbytor »

X, when you were working on shapeFile.js did you work out the csh file structure well enough to get the path point info from the file?

Nope. I didn't need that level of detail in the project I was working on. Getting this reverse engineered may take quite a bit of effort. Good luck :)
Mike Hale

csh file structure?

Post by Mike Hale »

I didn't think you had other wise you would already be reading the path points. But I had to ask.

I think I am making progress. I think I can determine the number of points. For each point I see where the point kind is stored. And for each point a set of 6 four byte values. I assume that is the x.anchor, x.left, x.right, y.anchor, y.left, and y.right. Although that may not be the order. I think each of those 4 bytes are IEEE floats. I looked in stream.js but didn't see a 'readFloat' function. Do you have one in some other of the xtools script? I had a look at ieee754.js but couldn't work out how to use that in a read function.
xbytor

csh file structure?

Post by xbytor »

I think each of those 4 bytes are IEEE floats. I looked in stream.js but didn't see a 'readFloat' function. Do you have one in some other of the xtools script?

I don't have to read 4byte floats anywhere, but I think this should work. If it does, let me know and I'll check it in.

Code: Select allStream.prototype.readFloat = function() {
  var self = this;
  var bin = self.readRaw(4);
  var v = IEEE754.binToDouble(bin);
  return v;
};
Mike Hale

csh file structure?

Post by Mike Hale »

I haven't had to read 4 byte floats before either. I assuming it's an IEEE float because the path points can be floats and the values in the csh file don't make any sense as integers.

When I tried using the new readFloat function I get an alert in photoshop saying 'too few hex digits'. Below is the script I am using to read the data( just a modified version of your ShapesFile.read )

Code: Select all/*======================================================================
This script requires xtool be installed http://ps-scripts.sourceforge.net/xtools.html

======================================================================*/


//@includepath "/c/Program Files/Adobe/xtools;/Developer/xtools"
//
//@include "xlib/stdlib.js"
//@include "xlib/Stream.js"
//@include "xlib/PresetsManager.jsx"
//@include "xlib/ShapesFile.js"
//@include "xlib/ieee754.js"

// add readFloat
Stream.prototype.readFloat = function() {
  var self = this;
  var bin = self.readRaw(4);
  var v = IEEE754.binToDouble(bin);
  return v;
};

// overwrite Shapes.read to explore extracting path points
ShapesFile.prototype.read = function(fptr) {
  var self = this;

  self.file = File(fptr);
  self.shapes = [];

  var str = Stream.readStream(self.file);

  var fileID = str.readKey();

  if (fileID != 'cush') {
    throw "File is not a custom shape file";
  }

  var re = /(\x00\w|\x00\d)(\x00\w|\x00\s|\x00\d|\x00\.|\x00\'|\x00\-)+(.|\n){10}\$[-a-z\d]+/g;//'

  var raw = str.str;
  var parts = raw.match(re);
  if (parts == null) {
    re = /(\x00\w|\x00\d)(\x00\w|\x00\s|\x00\d|\x00\.|\x00\'|\x00\-)+(.|\n){12}\$[-a-z\d]+/g;//'
    parts = raw.match(re);

    if (!parts) {
//       debugger;
      return undefined;
    }
  }

  for (var i = 0; i < parts.length; i++) {
    var p = parts;
    var sp = p.replace(/\x00/g, '').split('$');
   
    sp[0] = sp[0].match(/[\w\d][\w\s\d\.\'\-]+/)[0]; //'

    var shape = new CustomShapeInfo();
    shape.name = sp[0];
    var id = sp[1];
    shape.id = '$' + sp[1];
    var m = str.str.match(sp[1]);
    str.ptr = m.index + m[0].length;
    shape.y = str.readWord();//+ 2;
    shape.x = str.readWord();//+ 2;
    shape.h = str.readWord() - shape.y ;//- 2;
    shape.w = str.readWord() - shape.x;// - 2;

   str.readShort();// should be x00x06
   str.readWord();// lot's of padding ??
   str.readWord();// clean up later to avoid all these readWords
   str.readWord();
   str.readWord();
   str.readWord();
   str.readWord();
   str.readShort();// should be x00x08
   str.readWord();// lot's of padding ??
   str.readWord();
   str.readWord();
   str.readWord();
   str.readWord();
   str.readWord();
   str.readWord();// number of points?
   str.readShort()// should be x00x01
   str.readShort()// should be x00x01
   str.readWord();// lot's of padding ??
   str.readWord();
   str.readWord();
   str.readWord();
   str.readShort();
   str.readShort();// point kind?
   str.readFloat();// should be first path point data
   
   
   $.level = 1;
   debugger;   
   
    self.shapes.push(shape);
  }

  return self.shapes;
};

function main(index){
   var presetManager = new PresetsManager();
   var names = presetManager.getNames( PresetType.CUSTOM_SHAPES );
   var shapeInfo = CustomShapeInfo.getShapeInfo(names[index]);

}
// work with frist shape in presets
main(0);
xbytor

csh file structure?

Post by xbytor »

If that didn't work, I don't see any easy way of reading a 4byte float. I'll take a look at it again tomorrow.
Mike Hale

csh file structure?

Post by Mike Hale »

It seems from my internet search that there are several ieee floating point types. A 'single' is 32bits and a 'double' is 64 bits. From looking at the ieee754.js script in xtools it looks to me like it only handles the 'double' kind.

But more research about how Photoshop stores paths now has me thinking that the path points in a shape file are not stored as ieee floats. So while it would be nice to be able to read ieee 'single' when needed, it will not help here.

From the Adobe Photoshop File Formats Spec.
The two components are signed, fixed point numbers with 8 bits before the binary point and 24 bits after the binary point. Three guard bits are reserved in the points to eliminate most concerns over arithmetic overflow. Hence, the range for each component is 0xF0000000 to 0x0FFFFFFF representing a range of -16 to 16. The lower bound is included, but not the upper bound.

While that is talking about how paths are stored in an image file as a path resource, I think shape files use the a similar structure. It also tells me that I want to look for another way to handle the fact that the bounds in the csh file don't always match the bounds of the path used to create the shape.
xbytor

csh file structure?

Post by xbytor »

In xlib/ieee754/iee754-32.js, the 'compute()' function starts off with a 32bit float hex string and does the conversion to a float/double.
There is also a demo HTML page in the subdirectory that shows how to call the compute function. So it does appear that all the needed
bits are there if we ever need to implement read/writeFloat() methods.
Mike Hale

csh file structure?

Post by Mike Hale »

Good to know, thanks.

Also just FYI, I see that in XWatermark 1.5 you have a note saying "Fixed a problem with shape aspect ratio handling". I am finding that CustomShapeInfo.getShapeInfo() still can return wonky info. I have attached a psd and a csh file as examples.

In the psd there is one path. When I get the path bounds using Edit-transform path the info panel show the x,y as 0,0 and the w,h as 72,72.( ruler set to pixels ). Note the path is a circle but only has 3 path points. There is another shape in the csh file with a circle made with two points. The error for that shape is larger than the first shape.

When I use CustomShapeInfo.getShapeInfo() to get the bounds of the shape created with that path I get x,y -8,0 and w,h 88,78

If I get the bounding box for the path point anchors I get 4.88,0 and 62.26,54.02 While that still doesn't match the info in the csh file it is closer than the path bounds. So I don't think that bounds in the csh file is the path bounds. I think the bounds in the csh file is used with the path point info also stored in the csh file so that the path can be recreated independent of the document size or resolution.

I just thought you would like to know this in case you need to address this in the future.
xbytor

csh file structure?

Post by xbytor »

OK. Thanks. I'll check into it.