SPEC: Read 1376 byte binary file into uint16_t array overwrite item[16] with dec<7360> = 0X1cc0 overwrite item[22] with dec<4912> = 0X1330 Write file to disk sub prefix_hdr() { $hsize=1376; # Size of 16-bit grayscale tif header $hfn='d:/pic/misc/gray.3689x2462.hdr'; # Md5 ~29992 $brfn='6s-254550.7360x4912.blue.raw'; # photoshops $rsize=-s $brfn; $mutant='blue.7360x4912.tif'; open(H, "<$hfn"); binmode H; $bread=read(H, $hdr, $hsize); close H; printf("Read $bread B from $hfn\n"); @rgb=unpack("S*", $hdr); # RAW RGB UShort array printf("RGB[16]=%hu, [22]=%hu\n", $rgb[16], $rgb[22]); $rgb[16]=pack("S", 7360); # Overwrite 3689 with 7360 $rgb[22]=pack("S", 4912); # 2462 -> 4912 printf("FIXED? RGB[16]=0X%04hu, [22]=%hu\n", $rgb[16], $rgb[22]); } Read 1376 B from d:/pic/misc/gray.1376b.3689x2462.hdr RGB[16]=3689, [22]=2462 << PERFECT! Argument "&#9492;^\" isn't numeric in printf Argument "0^S" isn't numeric in printf FIXED? RGB[16]=0X0000, [22]=0 <<<<<<WRONG ----------------------------------------------------

File reads fine. Unpacks perfectly and the numbers print

Pack is not packing the unsigned short:

pack(TEMPLATE,LIST) S An unsigned short value. Template="S" List = one value, DECIMAL 7360

How does one do this in Perl

int xres=7360; uint16_t my_ui16[688]; ... my_ui16[16] = (uint16_t)xres; printf("Xres=%hu\n"); >> Xres=7360
============================================================

>> open my($outfh),'>:raw', 'stuff';

Opening the file, put it in BINMODE and reading into a blob worked.

Unpacking the binary blob into an intelligible unsigned int array also works.

But, writing does NOT work in BINmode? Reading didn't need ':raw<~!%_'

>> print $outfh pack 'S<*', @rgb; We skipped the part about overwriting the default values.

How is it possible to take a proven correct UINT16 array

read in Perl and overwrite 2 values? Generating a real, uint16 from scratch was the

obstacle. The PACK and UNPACK do not appear to do inverse operations.

Applying PACK() as documented with an 'S' produced unprintable junk.

The original array values printed perfectly as %uh, unsigned shorts.

How does one translate this C into perl?: </p

my_uint_16_var = (uint16_t) 7360;

It has to be a drop in replacement for the default value, the >>3689<< stock value, not ["&#9492;^\"] << ??

:RAW???

Those layers will also be ignored if you specifying a colon with no na +me following it. In that case the default layer for the operating sys +tem (:raw on Unix, :crlf on Windows) is used.

Binmode does away with any cr/lf funkiness.

regardless of platform, use binmode() on binary data, like images, for + example.
I am on Windoz, not *nix. Do I need :CRLF??? This is an OBSCURE Caveat!


In reply to Write 2 uint16_t numbers to file in Perl by BrianP

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.