Writing binary file using in Extendscript. Incorrect file size - binaryfiles

Further to my question here I'm writing a list of hex colours to a binary file from within Photoshop using Extendscript. So far so good.
Only the binary file written with the code below is 119 bytes. When cut and pasted and saved using Sublime Text 3 it's only 48 bytes, which then causes complications later on.
This is my first time in binary land, so I may be a little lost. I suspect it's an either an encoding issue (which could explain the 2.5 file size), or doing something very wrong trying to recreate the file in a literal, character for character sense. *
// Initially, my data is a an array of strings
var myArray = [
"1a2b3c",
"4d5e6f",
"a10000",
"700000",
"d10101",
"dc0202",
"c30202",
"de0b0b",
"d91515",
"f06060",
"fbbaba",
"ffeeee",
"303030",
"000000",
"000000",
"000000"
]
// I then separate them to four character chunks
// in groups of 8
var data = "1a2b 3c4d 5e6f a100 0070 0000 d101 01dc\n" +
"0202 c302 02de 0b0b d915 15f0 6060 fbba\n" +
"baff eeee 3030 3000 0000 0000 0000 0000";
var afile = "D:\\temp\\bin.act"
var f = new File(afile);
f.encoding = "BINARY";
f.open ("w");
// f.write(data);
// amended code
for (var i = 0; i < data.length; i++)
{
var bytes = String.fromCharCode(data.charCodeAt(i));
f.write(bytes);
}
f.close();
alert("Written " + afile);
* ...or it's the tracking on my VHS.

I'm rubbish at JavaScript but I have hacked something together that will show you how to write 3 bytes of hex to a file in binary. I hope it is enough for you to work out how to do the rest!
I saved this file as /Users/mark/StackOverflow/AdobeJavascript.jsx
alert("Starting");
// Open binary file
var afile = "/Users/mark/StackOverflow/data.bin"
var f = new File(afile);
f.encoding = "BINARY";
f.open ("w");
// Define hex string
str = "1a2b3c"
for(offset=0;offset<str.length;offset+=2) {
i = parseInt(str.substring(offset, offset+2), 16)
f.write(String.fromCharCode(i));
}
f.close();
alert("Done");
If you dump the data.bin you'll see 3 bytes:
xxd data.bin
00000000: 1a2b 3c
You can write more of your values by simply changing the string to:
str = "1a2b3c"+ "4d5e6f"+ "a10000";
I also discovered how to run ExtendScript from a shell script in Terminal which is my "happy place" so I'll add that in here for my own reference:
#!/bin/bash
osascript << EOF
tell application "Adobe Photoshop CC 2019"
do javascript "#include /Users/mark/StackOverflow/AdobeJavascript.jsx"
end tell
EOF
The corresponding reading part of this answer is here.

Related

`bytes.fromhex` and `to_bytes` method in Raku?

I have a Python3 function that combine two bytes, one use bytes.fromhex() method, and the other use to_bytes() method:
from datatime import datetime
def bytes_add() -> bytes:
bytes_a = bytes.fromhex('6812')
bytes_b = datetime.now().month.to_bytes(1, byteorder='little', signed=False)
return bytes_a + bytes_b
Is it possible to write a same function as above in Raku?(if so, How to control byteorder and signed params?)
as for byteorder, say convert number 1024 to bytes in Python:
(1024).to_bytes(2, byteorder='little') # Output: b'\x00\x04', byte 00 is before byte 04
as a contrast, convert number 1024 to Buf or Blob in Raku:
buf16.new(1024) # Output: Buf[uint16]:0x<0400>, byte 00 is after byte 04
is there any way to get Buf[uint16]:0x<0004> in the above example in Raku?
Update:
inspired by codesections, I try to figure out a solution similar to codesections's answer:
sub bytes_add() {
my $bytes_a = pack("H*", '6812');
my $bytes_b = buf16.new(DateTime.now.month);
$bytes_a ~ $bytes_b;
}
But still don't know how to use byteorder.
Is it possible to write a same function as above in Raku?
Yes. I'm not 100% sure I understand the overall goal of the function you provided, but a literal/line-by-line translation is certainly possible. If you would like to elaborate on the goal, it may also be possible to achieve the same goal in an easier/more idiomatic way.
Here's the line-by-line translation:
sub bytes-add(--> Blob) {
my $bytes-a = Blob(<68 12>);
my $bytes-b = Blob(DateTime.now.month);
Blob(|$bytes-a, |$bytes-b)
}
The output of bytes-add is printed by default using its hexadecimal representation (Blob:0x<44 0C 09>). If you'd like to print it more like Python prints its byte literals, you can do so with bytes-add».chr.raku, which prints as ("D", "\x[C]", "\t").
if so, How to control byteorder?
Because the code above constructs the Blob from a List, you can simply .reverse the list to use the opposite order.

How to send color images with ESC/POS?

I have an Epson CW-C6000 that I'm trying to control with ESC commands. I've gotten text to print, so I know I have the IP address, port, etc correct but cannot for the life of me get an image printed.
Here is my code (running from a Ruby on Rails server, with most of the image truncated):
streamSock = TCPSocket.new( "X.X.X.X", 9100 )
str = "~DYR:PRODIMG,B,P,183208,0,89504E470D...4AE426082" + "^XA" + "^FO150,150^IMR:PRODIMG.PNG^FS" + "^XZ"
streamSock.send( str , 0)
streamSock.close
The image is a .png I converted to hexadecimal with this site:
http://tomeko.net/online_tools/file_to_hex.php?lang=en
I'm mostly using page 10 of this PDF for reference:
https://files.support.epson.com/pdf/pos/bulk/esclabel_apg_en_forcw-c6000series_reve.pdf
Does anyone have a hint? Epson support staff was spectacularly unhelpful.
Also I'm sorry if my formatting is bad; I'm new here and will happily edit my post if something is wrong.
Alright I finally got it working. The command for printing a color .PNG is this:
~DYE:[Image Name].PNG,p,p,[Image Size],0,:B64:[Base64 String]:[CRC]
Things that tripped me up:
-You seem to need the .PNG extension on the file name, even though the Epson manual doesn't show that.
-[Image Size] is the number of characters in the Base64 string, even though the Epson manual says it should be the size of the original .PNG image file. If this is wrong the printer will hang and no longer accept input of any kind until restarted.
-There may be other options, but I could only get it working with a CRC of the hex CRC-16/XMODEM type.
Thanks to K J for his/her suggestions and coming along with me!
Perhaps this material can be used as an additional reference.
They seem to have a completely different command/data format than ESC/POS.
ESC/Label Command Reference Guide
Page 12
1.3.4 About Saving the Graphics and Label Formats in the Printer
With ESC/Label command, you can save graphics and label formats in the printer. The printer has a file system. Data saved in the printer is handled as files and is managed in the following way.
The file system does not have a hierarchy.
The printer has a non-volatile saving device, such as Flash ROM, and a volatile saving device, such as RAM, and different drive letters are allocated for each device.
Files are designated as
"<drive letter> colon <:> <file name> dot <.> <extension>".
Page 40-41
2.8 Printing Graphics
...Details have been omitted. Please refer to the actual document...
2.8.1 Registering a Graphic in a Printer and Printing It
...Pick up some from the content. Please refer to the actual document...
Delete the files that remain in the printer (^ID command).
Register the graphic in the printer (~DY command).
When registering a color graphic, you can use the PNG format. When registering a monochrome graphic, you can register the PNG format or the GRF format.
PNG format Monochrome and color graphics
GRF format Monochrome graphics
The reason to execute the step 1.
To ensure capacity of the storage memory necessary for print which application will perform.
2.8.2 Embedding a Graphic in the Field and Printing It
...Details have been omitted. Please refer to the actual document...
In Addition:
Page 104-106
~DY
[Name]
Save File
[Format]
~DY d: o ,f ,x ,t ,w ,data
...A table detailing the parameters is due, but omitted...
[Function]
...Further detailed explanations and figures of functions and parameters are due, but omitted...
Graphic data is handled as follows.
If the data format is binary, you can use any binary data as Parameter data. At this time, the size of Parameter data must be matched to the size specified in Parameter t.
If the data format is a hexadecimal character string, one character from 1. to 3. below is used as Parameter data. At this time, the size of Parameter data written in binary must be matched to the size specified in Parameter t.
0 to 9, A to F, and a to f in ASCII can be used as hexadecimal graphic data.
ASCII comma <,>, the parameter separator character, is used to separate lines. If a comma is input, processing is carried out as if ASCII 0 was input for the remainder of the line.
G to Y and g to z in ASCII can be used as repetition characters. For example, if I9 is input, processing is carried out as if 999 were input. The following table indicates the number of repetitions.
...Characters and repeat specified number of times table omitted...
Looking at the contents of this Technical Reference Guide, it seems that you can register images with tools instead of commands.
CW-C6000/C6500 Series Technical Reference Guide
Page 173-174
And page 288 outlines the Epson Inkjet Label Printer SDK and also describes the existence of sample programs.
#Farmbot26. I have been attempting this same using vb.Net and as you noted Epson support is not helpful. I'm not sure if it's the actual image data that is wrong, CRC, or the ZPL code as nothing helps. Here's 2 examples that have not worked.
`Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
zplImageData = Convert.ToBase64String(binaryData)
crc = calcrc(binaryData, binaryData.Length).ToString("X4")
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",P,P," & zplImageData.Length & ",0,:B64:" & zplImageData & ":" & crc & "^XZ"`
`Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
crc = calcrc(binaryData, binaryData.Length).ToString("X4") 'Calculate CRC
zplImageData = BitConverter.ToString(binaryData).Replace("-", "")
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",A,P," & zplImageData.Length & ",0,:B64:" & zplImageData & ":" & crc & "^XZ"`
This is the CRC example I have.
`Function calcrc(ByVal data() As Byte, ByVal count As Integer) As Integer
Dim crc As Integer = 0
For Each b As Byte In data
Dim d As Integer = CInt(b)
crc = crc Xor (d << 8)
For j = 0 To 7
If ((crc And &H8000) <> 0) Then
crc = (crc << 1) Xor &H1021
Else
crc = (crc << 1)
End If
Next
Next
Return crc And &HFFFF
End Function`
I have figured out another solution. Save the PNG Image using the Binary data. I found this when reading the Saved Backup file of Image data using the Epson Settings Utility.
~DYE:FILENAME.PNG,B,P,BINARYFILESIZE,0, BINARYIMGDATA
` Try
Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
Dim client As System.Net.Sockets.TcpClient = New System.Net.Sockets.TcpClient()
client.Connect(IP_TextBox1.Text.Replace(" ", ""), txtPort.Text)
Dim writer As System.IO.StreamWriter = New System.IO.StreamWriter(client.GetStream(), Encoding.UTF8)
Using mStream As New MemoryStream(binaryData)
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",B,P," & mStream.Length & ",0,"
writer.Write(zplToSend)
writer.Flush()
mStream.WriteTo(client.GetStream())
writer.Flush()
End Using
writer.Close()
client.Close()
MsgBox("Send Complete", MsgBoxStyle.OkOnly, "Complete")
Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.OkOnly, "ERROR")
End Try`
You can also open the image file in an IMAGE object and resize it as needed. I had to do this for the label size of the printer.

what does it mean files overflow_xxxx.bin while training glove

I'm training a word embedding model based on Glove method. While the algorith shows a logger like:
$ build/cooccur -memory 4.0 -vocab-file vocab.txt -verbose 2 -window-size 8 < /home/ignacio/data/GUsDany/corpus/GUs_regulon_pubMed.txt > cooccurrence.bin
COUNTING COOCCURRENCES
window size: 8
context: symmetric
max product: 13752509
overflow length: 38028356
Reading vocab from file "vocab.txt"...loaded 145223095 words.
Building lookup table...table contains 228170143 elements.
Processing token: 5478600000
The home directory of Glove is filled with files caled overflow_0534.bin. Can someone tell whether all is going well?
Thanks
Everything is OK.
You can view the source code of Glove cooccur program at Github.
At the line 57 of the file:
long long overflow_length; // Number of cooccurrence records whose product exceeds max_product to store in memory before writing to disk
If your corpus has too many co-occurrence records, then there will be some data to be written into some temp bin disk files.
while (1) {
if (ind >= overflow_length - window_size) { // If overflow buffer is (almost) full, sort it and write it to temporary file
qsort(cr, ind, sizeof(CREC), compare_crec);
write_chunk(cr,ind,foverflow);
fclose(foverflow);
fidcounter++;
sprintf(filename,"%s_%04d.bin",file_head,fidcounter);
foverflow = fopen(filename,"w");
ind = 0;
}
The variable overflow_length depends on your memory settings.
Line 463:
if ((i = find_arg((char *)"-memory", argc, argv)) > 0) memory_limit = atof(argv[i + 1]);
Line 467:
rlimit = 0.85 * (real)memory_limit * 1073741824/(sizeof(CREC));
Line 470:
overflow_length = (long long) rlimit/6; // 0.85 + 1/6 ~= 1

byte reverse hex with python

I have a .bin file, and I want to simply byte reverse the hex data. Say for instance # 0x10 it reads AD DE DE C0, want it to read DE AD C0 DE.
I know there is a simple way to do this, but I am am beginner and just learning python and am trying to make a few simple programs to help me through my daily tasks. I would like to convert the whole file this way, not just 0x10.
I will be converting at start offset 0x000000 and blocksize/length is 1000000.
EDIT:
here is my code, maybe you can tell me where i am messing up.
def main():
infile = open("file.bin", "rb")
new_pos = int("0x000000", 16)
chunk = int("1000000", 16)
data = infile.read(chunk)
save(data)
def save(data):
with open("reversed", "wb") as outfile:
outfile.write(data)
main()
how would i go about coding it to byte reverse from CDAB TO ABCD?
if it helps any the file is exactly 16MB
You can just swap the bytes manually like this:
with open("file.bin", "rb") as infile, open("reversed", "wb") as outfile:
data = infile.read()
for i in xrange(len(data) / 2):
outfile.write(data[i*2+1])
outfile.write(data[i*2])

Showing bits in objects

I'm reading a book about C++. The author shows this enum:
[Flags] enum class FlagBits{ Ready = 1, ReadMode = 2, WriteMode = 4,
EOF = 8, Disabled = 16};
FlagBits status = FlagBits::Ready | FlagBits::ReadMode | FlagBits::EOF;
and he says that status is equals to '0000 0000 0000 0000 0000 0000 0000 1011', but when I write status to console:
Console::WriteLine(L”Current status: {0}”, status);
it shows: 'Current status: Ready, ReadMode, EOF'. How can he know it, and how can I write status to console to show its binary form?
You should look into System::Convert::ToString
int main(array<System::String ^> ^args)
{
FlagBits status = FlagBits::Ready | FlagBits::ReadMode | FlagBits::EOF;
Console::WriteLine(L"Current status: {0}", System::Convert::ToString( ( int ) status, 2 ) );
Console::ReadLine();
return 0;
}
Output: Current Status: 1011
Edit: if you want the empty zero 'padding' just do:
Console::WriteLine(L"Current status: {0}", System::Convert::ToString( ( int ) status, 2 )->PadLeft( 32, '0' ) );
If you want it segmented into byte size pieces, then just split up the result and insert space / hyphens.
The first thing will be to cast the value to an integer. I'm not sure of the best way to do this in C++/CLI, but in C it would be (int)status.
C++ does not offer a way to display a value in binary, but it does allow hexadecimal. Here's the statement for that:
Console::WriteLine(L"Current status: {0:x}", (int)status);
The output should be 0000000b.
First, the author knows that because status is being OR'ed with the three enum values
FlagBits::Ready = 1 // Binary 0001
FlagBits::ReadMode = 2 // Binary 0010
FlagBits::EOF = 8 // Binary 1000
Just add these three values together and you'll get the 1011 the author talks about (you can truncate all leading zeroes). If you didn't come accross bitwise operations by now: The pipe | is used to do a bitwise OR-Operation on the values. You just add up all digits that are 1 like this:
0001
0010
+1000
-----
=1011
Second: Like my previous poster, Mark Ransom, I don't actually know if C# is capable of printing values in binary form like the "oldschool" printf() function in C or the std::cout in C++ are able to. First thought would be to use the BitConverter class of .NET and writing such a binary-print-function myself.
Hope that helps.
EDIT: Found an example here using the BitConverter I mentioned. I didn't check it in detail, but on first looks it seems alright: http://www.eggheadcafe.com/software/aspnet/33292766/print-a-number-in-binary-format.aspx

Resources