Help with Base64 Encoded image

Discussions relating to writing software in ILE RPG (RPG IV). This includes both fixed and free format RPG.
Post Reply
gmalchow
Posts: 8
Joined: Fri Aug 30, 2024 8:40 pm

Help with Base64 Encoded image

Post by gmalchow »

Hello,
I want to preface this with I feel like I am missing something very simple, thus, I am feeling pretty stupid right now.

I'm currently parsing an xml file that contains a base64 encoded value that is a png image file.

I'm unable to successfully create a properly formatted/encoded png image file. I suspect the problem is that I am not using the correct ccsid when writing the decoded string to file.

I am assuming the encoding is utf-8 because the data is originating from a utf-8 encoded xml file. As I said, I suspect the problem is that I am using the wrong ccsid. If the ccsid is not utf-8 than I'm not sure what it needs to be. I don't expect someone to tell me what the correct ccsid is, but I'm hoping someone might see something I am doing incorrectly and point that out to me.

Below is the program I am using.

Code: Select all

**free
ctl-opt dftactgrp(*no) actgrp(*caller);
ctl-opt BNDDIR('BASE64');

/COPY YAJL/QRPGLESRC,IFSIO_H
/COPY base64_h

dcl-s filePath varchar(128) inz('/home/gmalchow/field data mlw.xml');
dcl-s pngFile varchar(128) inz('/home/gmalchow/signature.png');

dcl-s chr64   varchar(32767);
dcl-s chr64Out varchar(32767);

dcl-s fd int(10);
dcl-s len int(10);

//dcl-ds conv qualified;
//  base varchar(32767) pos(1);
//  chrUTF8 varchar(32767) ccsid(*utf8) pos(1);
//END-DS;

chr64  ='89504e470d0a1a0a0000000d494844520000012c000000c80802000000ddbd4b020000+
         000373424954050605330b8d800000101649444154789ceddd4f681b571e07f0d7c587+
         275060045ed040031e6821631a880c8148b007abe410050ab5d905cb5048e55d48ec2d+
         2456034ddc1eb24e16ba7202593b855d6b0301bbb0601976b173583a3e04a4428bbc10+
         c8045290a1050912d0400d7a0783f730dab1acff76e7cd4fb6bf9f93a2c89ab1acefcc+
         fbf39b376fedeeee3200a0f32bea1d0038e91042006208210031841080184208400c21+
         04208610021043080188218400c41042006208210031841080184208400c2104208610+
         021043080188218400c41042006208210031841080184208400c210420861002104308+
         0188218400c41042006208210031841080184208400c21042086100210430801882184+
         00c41042006208210031841080184208400c2104208610021043080188218400c41042+
         006208210031841080184208400c2104208610021043080188218400c4104200620821+
         0031841080184208400c2104208610021043080188218400c410420062082100318410+
         80184208400c2104208610021043080188218400c41042006208210031841080184208+
         400c21042086100210ebe910a61fa719634208ea1d0190a8774398bc954c5c4930c638+
         e75337a7a8770740961e0da16559a97b29e79fc5ed22e1ce0048d5a3211cbf355efb4f+
         ce38d59e00c8d6a3214c7f91def7ef1da2fd0090af1743f8fec7ef0783c17d4f218470+
         7cf55c088510b1b3b1fa67158a5d01f044cf8570e6ceccf4f5e9ba278585590a38b67a+
         2e8462a749de305508c7586f8570e1ab854828d2f83ce72e8f8e0a218e5fb02dcba2de+
         05388cde0a61f679363e166f7c3ee00fb8bba1cbd72e174bc76dee51511454351c45bd+
         15c280d23c6c8adfe59199c4c58436a0256f25dd7ddb36263e99f0602be6b6e9c156c0+
         5d3d14c2f4e374e8dd50e3f385ad42e094cb67c2fcf33c636cf3e5a6bb6fdbce0e638c+
         954a25a91b09f7879dc7c95b49d99beba8b055a0dd8123a18742b8696edac5a28cb148+
         6caf67683c33b401cddd6dd9a90e9d69927949781f678c0583c1f14fc63bbef8d05455+
         b5abde33ab19edb4967a98eaf82352150a85e3d7f7765d0f85b06c959dc743e7869cc7+
         b9ef724d3b8a87666c18f648cff8efc6e71eccb9f8ce6d38a3be01eef259bd564009d8+
         1bcafe90d5cfe8a97b29da5e62eedb5ce4e326236d50ab57429859cdf8149ffd78fde9+
         ba12a8e904ba5d2e53d82ad8210c9d0be5cdbccbefde4259540f316a409577720887c3+
         e62b9331268a223a1c658c8d5c1ab9fb97bb9236d7d18b1f5fc4de6928bd80fd7a2584+
         428858b8fad732b7ccc181c1eae397a6feaeeeeeb6b401cd89818ffbdc7df356b8e0ce+
         d697be5e92b4156d40b3d3ee74c6a2c3d1c28f641db3d21be24ee991d02b215ccbad8d+
         7c38623f2e140adae96a2730b39a692ca0f98522e148b95c3d2f8543e185af16dc7dff+
         a62c519dc4e39c6fbe9239202418634c1d509d27161f2e4edcf0626cb6913ea06b9ae6+
         cd277c74f54a084b5b7b87cc62a918be501de52bbc76ff289e59cd0cead5336de24aa2+
         58f462c250e1d506f6c8872352c72a2ccb72dadb0efdb4cbad892e29a794c495c4e673+
         0f47a18fa09e08a110427fafe65b52d30994712521e7bc50dacb7669db9326535fcd63+
         99e3858aa2f8b84fe9db37b33a7d7d7aea06c1088df6b6967e9c2e6f973bbff404eb89+
         10665633d1f351fbb1f9d254dfae36a5d28fd3a1b3eecf2270ce2ba2e2fcd39baf48c0+
         1fd89b34937989b2cfef9b7f34cf1ababadccfd79fae4bdc700bd6b62514cc52b4d313+
         21cc3fcfc72efd7f54e695a9fe5a751e3b33872e1242a8fd7b5d2635a8b679b15bb89f+
         3badd0f21b89b1e77ddce7f3f9fcf5294cdd492dadca1a106a257125912fe435ffde34+
         6ffa717ae64f33a37f189db836616c181eef4f6feaebfc12f9cc9f4ca70f63fe60ea67+
         aa4d5349152d9c73b1bd776c0e69a1cc6ac61916928407b83705d6dabb9a78232a3b95+
         c6ff5235d5d830eca90bcff898cff8af11f92012f007f4015d7f579ff974c6f58afc23+
         ad2742587b5e2abf2eabe1ea3f9d36aabb38e7b54323da80e6417595cfef73468084cc+
         4e21673c5bccea6a939198d467a9891b13de84d0d8308c6f0db3686ee636cb7de5d870+
         ac76e52ea845df1c35368cda9251cbb2eca1d1a99b53b73fbb2d638b4288e2cf7b23a2+
         d1e168e18df41086df0be7b7aa8501aed7a3d70af80343ea90f8b979ce39e7f20a4a85+
         10735fcd256f26c73f1e37be37a217a22b0f57e6efcceb01ddf5c9dee384fe4c68fe60+
         d696863aeda8ec4f59495b0c0402dcb7af3954fa51fa00a9cfe713afbda85c5314a5c2+
         2aceb4649dd417a9b9bfceddfed4cda35b61ab603c338c9ce1ebf3e9ba3e1e1f0f9ddb+
         3baac62ec5925f245141da067d080ba582f6f65e089d1185d4ef65b55e42e7422bff5a+
         d9f794fc85a4c217c2f34fe6edc745267166321008889f45edf06f2dcef98b572f5cd9+
         901022fd75dad830d47e35723eb2f4a8e5a88ff26bc59bd1af23aa07425828c43edf2b+
         2fb427b587e243f96559559d9cf3fa45343c19267036aa71972f0aa9658f7958a59683+
         4089b1c4cc8399d9ebb387de446635633c330413a1b3a195272b1d5fafbda32dfc7b41+
         f6d0d7d145df27b4b6f7be2e4288e42749c658fa66baf54fb861ffa94f3fad7b3036a3+
         6bba3d5367ed58f236c739b72c4b09b6ec764687a305f3f05b9ff9624608317f7f7ef1+
         fee2e495c96e7e647478b4bc85f9fa96e84358db169d7b3057b6ca9665d5762a6428ef+
         ecfb4e288a9259cd48dd22632c722e92fd3ecb18e33b5c5ee1b87e46673b1dba9d9aa6+
         1d7a8e6ef6ceec41af2c4387b03dfa10d64e19bdf8f1857e465714e9cb8cfaf657940c+
         ea8385b2f43361ec52ccde0af773a9bf6365a72298c87d9b6bf582c45822b321fda0e3+
         c83fcf277f9f5cfe7ad9b32d1e2dc421ccac6694537b5f4761096f566470aeeeb3852f+
         843d3a5a6f33c698b56d499dadb684a5695aa5d27c6c86d9573c7958cf59b48af1b1b8+
         f10cf531cd11875008e15c3ac8180b0403dd9f22ec751c0ea7b6235ab57de8373b80c1+
         b3830b7f5f280ae9d76d6841adfdb57c97cf5ffe251fe081d87b12ec0f767ce5c9441c+
         c28aa83883e9eb4fd7a3e7a3dd9f220e5156ba77ba6b989328ee787141d3c8c511d334+
         15c9cbfa2b7e85edb0ca76cb3321632c3e165ffe77b57d68be34bb5905c36ea4082146+
         af8d1e687fec6effec9d592f97b73b428843582814463facfe458d9c71a01ebffac101+
         a69eecf839f5225a7ffd2481deef4549877e46cfff375f5ba62783cfef5314c55ee7a2+
         8dc46f13763f6dea5e8704da9f9e7d971ecef9caa315c6589b3e67adcc6a66e4627572+
         829fe228da6e441cc24020e09cfa8a3f155917cb483b83fb91b70fb082907371773018+
         b42cab717ed4b3fb908a3e217bdd617baeb549937bbff8587ce5d90a634cebd7ecc5e0+
         5a315f36c973f842b89bb11623673897c8cc7e36eb591bf808210e61f175d1fe030b21+
         ec468ba2286dfe4e43f121a7c6ed40756de3637b0b0d8edf1c57fc4add17cba34b7b19+
         1b7a6f48f6c236fc145755b576f5ba563445638c2dde5f8c9c8fb419125b78d27c7d8a+
         43ac8217198e2c3cc66a17fb500fccf4097b4a70fde9faec9d6a0d87ddd91b8a0f395f+
         8b85af16a66e4e992fcdda321afb0bd48de5af976b6f78b8f6b735f307b36e38347131+
         619f84650f9306fd410f0a74f266bee9ad75eaa4eea5eefef92e632cfd9f749b639fdd+
         4c689ad2f62d97b90773a93bfbca0f27af4c6e6e62b58b7d8843a89eaaf68eb2dfd59f+
         d6f2cb792739935727e7bf9c77ae33b435d628b7ca8fdde8aa957d95adeb3239455575+
         173ab92bfd383da80f8e0c8fccfd5de27aa781fe00dbe9f62e3af605256b8fd6ca3fb7+
         3c739a6f4cf6ff3e611d45512effe1b2fdb87111d7c9ab938dbb31ffe5bcecb536ec23+
         cb51411c4267d5b38275e0b9f2f150fd52d6f6dfbbf6805ded40368c852646127617b4+
         f6679dd911799378b9e7b9f8583c762996cfc95defd41216f777f55bccdf9bb78758e6+
         9e753e2e345d2b79e9cb6ae9f6f4f56921c4fb1fbfcf18b307429b7e929cf3d0d95063+
         895297233dddb02f823b2a953ac42174c603921f1d78f0bad55288b507ec99fb33acd9+
         7d6622ef453a2efb2b63bd7a67dd2aedece10bc73a0abd132a5be55677d76934fd689a+
         31961a49b55a1931fba8da4e99bcdaa4585451f63ad89cf36ffef10d63acfd25bc892b+
         89958dfae689b3c49ecd89509759ca7d9bab3b46388780ba86b4d43b111cc62ea9db9f+
         dfdeddddcde6b292de3f7a25ba9259493d4cd53d9fdfccc77e1bebf8e3e572f9a05bb4+
         7fa3a616ffb1b8b6be663fae542ad39f4d1ff4cdbb54a9546edfbb3df9f964f71f6cb9+
         5c2e168bbbbbbbdf18df1c6ea32fcc1707fd11e7d368faa1552a95eedf6ae4ea48dd33+
         f6afd36ac7e27f8c77ffe6b2119f09edf53fe5adfc69affc575b236e0b9d0bad7fd779+
         e931bb815a2a95221fb51b3cac35756daad5a266ebb97567b0debed6a19b373c04ce79+
         a958e23edea672ad8ea228760b223a1c6d35171ff9a8dd9c505d8fbd1bf6a731fec9f8+
         c2f70b6cfff94a08d165a7a0b055b02ccb9ebaace534889aeed8d243afd7bc6a833884+
         9aa631c6f29bb23a48aaa2b69a9453fabb2d5b090683d927d9a6c3128d0a5b85a65b4c+
         de4ad6fde1171f2dcaab20e17dbcfdd45f1b2b8f568c0da3ae86e6ee9fef669f4859eb+
         60e9e1d2ccc519b6bf1fd1fd54aa36a07950f12f15f145bd7637c0999c709da66a66c1+
         6cda9399bcd4d5b5700715be10aeebdbd8c44e9343bbbc0a81f276f99714c74587a3d1+
         e1a8f9d25c7fba1e3a178a0e4725adf763731a08362184eb37c3eb65f4973249557c5d+
         acbb60c22129f91337261a47f9cc97e6fc97f38d2f5e7ab824eb0ebe7d2e1c60f533fa+
         f4f5690f5667ab6b319eb405118f790887ce0eb559e8c175a55269f1fea273265c7fba+
         3e7163c2b2ac36fda5901e9271a19daaa8aa5f25bf53ef419dcccad2631ec2f858dcc5+
         f5055bad4991bc95b40763eafa8db14bb1c5fb8bed7b2c935727d7726b6eeda14355d5+
         4c2ed34de55a4ff17861e21e71cc43288458ceb9769e69d55149dd4bd5f56a0e64e9e1+
         925374e216b55fe57dfca4b5eb8ea8631e42ce39f3ae357a786b7f5b1bfadd50e7d775+
         cd8e9f67b740855f827ec943d94221b96b46b925ffcffcdc83b9e2eb22636cf483d1a6+
         43acdd13427453c00dbde0addddd5dea7d90ebadb36fed3e3fe6bf6353a3d746477f33+
         7a88ab8dc063c7bc39ca98dc3b72f632dec78f4a2be0843b0121dca2de0122cbdf2d9b+
         6687152ea0179c80105ea0de0122212d8495e78f84e31fc2d0e913da249377330f70d7+
         f11f9801e871c7ff4c08d0e31042006208210031841080184208400c21042086100210+
         43080188218400c41042006208210031841080184208400c2104208610021043080188+
         218400c41042006208210031841080184208400c2104208610021043080188218400c4+
         1042006208210031841080184208400c2104208610021043080188218400c410420062+
         08210031841080184208400c2104208610021043080188218400c41042006208210031+
         841080184208400c2104208610021043080188218400c4104200620821003184108018+
         4208400c2104208610021043080188218400c41042006208210031841080184208400c+
         2104208610021043080188218400c41042006208210031841080184208400c21042086+
         100210fb1f17e776dcedd91c0e0000000049454e44ae426082';

%len(chr64Out) = %len(chr64Out : *MAX);

len = base64_decode( %addr(chr64:*data): %len(chr64)
                   : %addr(chr64Out:*data): %len(chr64Out:*MAX));

unlink(pngFile);

fd = open( pngFile
         : O_CREAT + O_EXCL + O_WRONLY + O_INHERITMODE
         + O_CCSID
         : 0
         : 1208
         : 0 );

callp write(fd: %addr(chr64Out:*data):len);

callp close(fd);

*inlr = *on;

For what it is worth, the image is a picture of a signature. The signature will eventually be used for generating "Signed" documentation.

Thank you,
Grizz
Scott Klement
Site Admin
Posts: 879
Joined: Sun Jul 04, 2021 5:12 am

Re: Help with Base64 Encoded image

Post by Scott Klement »

Hi Grizz,

Nice to hear from you... haven't heard your name in a long time!

The basic problem with your example is that the data isn't base64 encoded. I know that because Base64 data would look like the following

Code: Select all

iVBORw0KGgoAAAANSUhEUgAAASwAAADICAIAAADdvUsCAAAAA3NCSVQFBgUzC42AAAAQFklEQVR4
nO3dT2gbVx4H8NfFhydQYARe0EADHmghYxqIDIFIsAer5BAFCrXZBctQSOVdSOwtJFYDTdwesk4W
unICWTuFXWsDAbuwYBl2sXNYOj4EpEKLvBDIBFKQoQUJEtBADXoHg/cw2rGs/3bnzU+2v5+Tosia
sazvzPvzmzdv7e7uMgCg8yvqHQA46RBCAGIIIQAxhBCAGEIIQAwhBCCGEAIQQwgBiCGEAMQQQgBi
base64 data is encoded into 64 different text characters (A-Z, a-z, 0-9, +, /) and sometimes padded with equal signs. So you can see above that there's a lot of letters, some numbers, some symbols. Both upper/lowercase letters exist (since upper/lower case letters make up 52 of the 64 text characters.) So it looks like that.

Your data looks like this (excerpt):

Code: Select all

chr64  ='89504e470d0a1a0a0000000d494844520000012c000000c80802000000ddbd4b020000+
         000373424954050605330b8d800000101649444154789ceddd4f681b571e07f0d7c587+
         275060045ed040031e6821631a880c8148b007abe410050ab5d905cb5048e55d48ec2d+
         2456034ddc1eb24e16ba7202593b855d6b0301bbb0601976b173583a3e04a4428bbc10+
         c8045290a1050912d0400d7a0783f730dab1acff76e7cd4fb6bf9f93a2c89ab1acefcc+
         fbf39b376fedeeee3200a0f32bea1d0038e91042006208210031841080184208400c21+
         04208610021043080188218400c41042006208210031841080184208400c2104208610+
Notice that the data is all 0-9 or A-F? There are only 16 possible characters... that's not base64, it's base 16 -- better known as "hexidecimal".

IBM has a routine called cvtch() that can convert textual hex data (i.e. hex data where each nibble occupies one character like your data) to bytes (where each byte represents two nibbles). The only caveat is that cvtch() does require the letters to be uppercase, whereas yours are lowercase... but that's easy to fix with %XLATE.

Also, you are concerning yourself with CCSIDs, but... this isn't text data, so that doesn't make sense. CCSIDs represent how TEXT (i.e. character data) is encoded. But a PNG is an image file, it isn't character... so it's important that software not treat it as text, if it does, it'll corrupt it.

This is how I'd code your program:

Code: Select all

**free
ctl-opt dftactgrp(*no) actgrp(*caller);
ctl-opt BNDDIR('BASE64');

/COPY YAJL/QRPGLESRC,IFSIO_H
/COPY base64_h

dcl-s filePath varchar(128) inz('/home/gmalchow/field data mlw.xml');
dcl-s pngFile varchar(128) inz('/home/gmalchow/signature.png');

dcl-s chr64   varchar(32767);
dcl-s chr64Out varchar(32767);

dcl-s fd int(10);
dcl-s len int(10);

dcl-pr cvtch extproc(*dclcase);
  target pointer value;
  source pointer value;
  source_len int(10) value;
end-pr;

dcl-s ucChr64 varchar(32767);

//dcl-ds conv qualified;
//  base varchar(32767) pos(1);
//  chrUTF8 varchar(32767) ccsid(*utf8) pos(1);
//END-DS;

chr64  ='89504e470d0a1a0a0000000d494844520000012c000000c80802000000ddbd4b020000+
         000373424954050605330b8d800000101649444154789ceddd4f681b571e07f0d7c587+
         275060045ed040031e6821631a880c8148b007abe410050ab5d905cb5048e55d48ec2d+
         2456034ddc1eb24e16ba7202593b855d6b0301bbb0601976b173583a3e04a4428bbc10+
         c8045290a1050912d0400d7a0783f730dab1acff76e7cd4fb6bf9f93a2c89ab1acefcc+
         fbf39b376fedeeee3200a0f32bea1d0038e91042006208210031841080184208400c21+
         04208610021043080188218400c41042006208210031841080184208400c2104208610+
         021043080188218400c41042006208210031841080184208400c210420861002104308+
         0188218400c41042006208210031841080184208400c21042086100210430801882184+
         00c41042006208210031841080184208400c2104208610021043080188218400c41042+
         006208210031841080184208400c2104208610021043080188218400c4104200620821+
         0031841080184208400c2104208610021043080188218400c410420062082100318410+
         80184208400c2104208610021043080188218400c41042006208210031841080184208+
         400c21042086100210ebe910a61fa719634208ea1d0190a8774398bc954c5c4930c638+
         e75337a7a8770740961e0da16559a97b29e79fc5ed22e1ce0048d5a3211cbf355efb4f+
         ce38d59e00c8d6a3214c7f91def7ef1da2fd0090af1743f8fec7ef0783c17d4f218470+
         7cf55c088510b1b3b1fa67158a5d01f044cf8570e6ceccf4f5e9ba278585590a38b67a+
         2e8462a749de305508c7586f8570e1ab854828d2f83ce72e8f8e0a218e5fb02dcba2de+
         05388cde0a61f679363e166f7c3ee00fb8bba1cbd72e174bc76dee51511454351c45bd+
         15c280d23c6c8adfe59199c4c58436a0256f25dd7ddb36263e99f0602be6b6e9c156c0+
         5d3d14c2f4e374e8dd50e3f385ad42e094cb67c2fcf33c636cf3e5a6bb6fdbce0e638c+
         954a25a91b09f7879dc7c95b49d99beba8b055a0dd8123a18742b8696edac5a28cb148+
         6caf67683c33b401cddd6dd9a90e9d69927949781f678c0583c1f14fc63bbef8d05455+
         b5abde33ab19edb4967a98eaf82352150a85e3d7f7765d0f85b06c959dc743e7869cc7+
         b9ef724d3b8a87666c18f648cff8efc6e71eccb9f8ce6d38a3be01eef259bd564009d8+
         1bcafe90d5cfe8a97b29da5e62eedb5ce4e326236d50ab57429859cdf8149ffd78fde9+
         ba12a8e904ba5d2e53d82ad8210c9d0be5cdbccbefde4259540f316a409577720887c3+
         e62b9331268a223a1c658c8d5c1ab9fb97bb9236d7d18b1f5fc4de6928bd80fd7a2584+
         428858b8fad732b7ccc181c1eae397a6feaeeeeeb6b401cd89818ffbdc7df356b8e0ce+
         d697be5e92b4156d40b3d3ee74c6a2c3d1c28f641db3d21be24ee991d02b215ccbad8d+
         7c38623f2e140adae96a2730b39a692ca0f98522e148b95c3d2f8543e185af16dc7dff+
         a62c519dc4e39c6fbe9239202418634c1d509d27161f2e4edcf0626cb6913ea06b9ae6+
         cd277c74f54a084b5b7b87cc62a918be501de52bbc76ff289e59cd0cead5336de24aa2+
         58f462c250e1d506f6c8872352c72a2ccb72dadb0efdb4cbad892e29a794c495c4e673+
         0f47a18fa09e08a110427fafe65b52d30994712521e7bc50dacb7669db9326535fcd63+
         99e3858aa2f8b84fe9db37b33a7d7d7aea06c1088df6b6967e9c2e6f973bbff404eb89+
         10665633d1f351fbb1f9d254dfae36a5d28fd3a1b3eecf2270ce2ba2e2fcd39baf48c0+
         1fd89b34937989b2cfef9b7f34cf1ababadccfd79fae4bdc700bd6b62514cc52b4d313+
         21cc3fcfc72efd7f54e695a9fe5a751e3b33872e1242a8fd7b5d2635a8b679b15bb89f+
         3badd0f21b89b1e77ddce7f3f9fcf5294cdd492dadca1a106a257125912fe435ffde34+
         6ffa717ae64f33a37f189db836616c181eef4f6feaebfc12f9cc9f4ca70f63fe60ea67+
         aa4d5349152d9c73b1bd776c0e69a1cc6ac61916928407b83705d6dabb9a78232a3b95+
         c6ff5235d5d830eca90bcff898cff8af11f92012f007f4015d7f579ff974c6f58afc23+
         ad2742587b5e2abf2eabe1ea3f9d36aabb38e7b54323da80e6417595cfef73468084cc+
         4e21673c5bccea6a939198d467a9891b13de84d0d8308c6f0db3686ee636cb7de5d870+
         ac76e52ea845df1c35368cda9251cbb2eca1d1a99b53b73fbb2d638b4288e2cf7b23a2+
         d1e168e18df41086df0be7b7aa8501aed7a3d70af80343ea90f8b979ce39e7f20a4a85+
         10735fcd256f26c73f1e37be37a217a22b0f57e6efcceb01ddf5c9dee384fe4c68fe60+
         d696863aeda8ec4f59495b0c0402dcb7af3954fa51fa00a9cfe713afbda85c5314a5c2+
         2aceb4649dd417a9b9bfceddfed4cda35b61ab603c338c9ce1ebf3e9ba3e1e1f0f9ddb+
         3baac62ec5925f245141da067d080ba582f6f65e089d1185d4ef65b55e42e7422bff5a+
         d9f794fc85a4c217c2f34fe6edc745267166321008889f45edf06f2dcef98b572f5cd9+
         901022fd75dad830d47e35723eb2f4a8e5a88ff26bc59bd1af23aa07425828c43edf2b+
         2fb427b587e243f96559559d9cf3fa45343c19267036aa71972f0aa9658f7958a59683+
         4089b1c4cc8399d9ebb387de446635633c330413a1b3a195272b1d5fafbda32dfc7b41+
         f6d0d7d145df27b4b6f7be2e4288e42749c658fa66baf54fb861ffa94f3fad7b3036a3+
         6bba3d5367ed58f236c739b72c4b09b6ec764687a305f3f05b9ff9624608317f7f7ef1+
         fee2e495c96e7e647478b4bc85f9fa96e84358db169d7b3057b6ca9665d5762a6428ef+
         ecfb4e288a9259cd48dd22632c722e92fd3ecb18e33b5c5ee1b87e46673b1dba9d9aa6+
         1d7a8e6ef6ceec41af2c4387b03dfa10d64e19bdf8f1857e465714e9cb8cfaf657940c+
         ea8385b2f43361ec52ccde0af773a9bf6365a72298c87d9b6bf582c45822b321fda0e3+
         c83fcf277f9f5cfe7ad9b32d1e2dc421ccac6694537b5f4761096f566470aeeeb3852f+
         843d3a5a6f33c698b56d499dadb684a5695aa5d27c6c86d9573c7958cf59b48af1b1b8+
         f10cf531cd11875008e15c3ac8180b0403dd9f22ec751c0ea7b6235ab57de8373b80c1+
         b3830b7f5f280ae9d76d6841adfdb57c97cf5ffe251fe081d87b12ec0f767ce5c9441c+
         c28aa83883e9eb4fd7a3e7a3dd9f220e5156ba77ba6b989328ee787141d3c8c511d334+
         15c9cbfa2b7e85edb0ca76cb3321632c3e165ffe77b57d68be34bb5905c36ea4082146+
         af8d1e687fec6effec9d592f97b73b428843582814463facfe458d9c71a01ebffac101+
         a69eecf839f5225a7ffd2481deef4549877e46cfff375f5ba62783cfef5314c55ee7a2+
         8dc46f13763f6dea5e8704da9f9e7d971ecef9caa315c6589b3e67adcc6a66e4627572+
         829fe228da6e441cc24020e09cfa8a3f155917cb483b83fb91b70fb082907371773018+
         b42cab717ed4b3fb908a3e217bdd617baeb549937bbff8587ce5d90a634cebd7ecc5e0+
         5a315f36c973f842b89bb11623673897c8cc7e36eb591bf808210e61f175d1fe030b21+
         ec468ba2286dfe4e43f121a7c6ed40756de3637b0b0d8edf1c57fc4add17cba34b7b19+
         1b7a6f48f6c236fc145755b576f5ba563445638c2dde5f8c9c8fb419125b78d27c7d8a+
         43ac8217198e2c3cc66a17fb500fccf4097b4a70fde9faec9d6a0d87ddd91b8a0f395f+
         8b85af16a66e4e992fcdda321afb0bd48de5af976b6f78b8f6b735f307b36e38347131+
         619f84650f9306fd410f0a74f266bee9ad75eaa4eea5eefef92e632cfd9f749b639fdd+
         4c689ad2f62d97b90773a93bfbca0f27af4c6e6e62b58b7d8843a89eaaf68eb2dfd59f+
         d6f2cb792739935727e7bf9c77ae33b435d628b7ca8fdde8aa957d95adeb3239455575+
         173ab92bfd383da80f8e0c8fccfd5de27aa781fe00dbe9f62e3af605256b8fd6ca3fb7+
         3c739a6f4cf6ff3e611d45512effe1b2fdb87111d7c9ab938dbb31ffe5bcecb536ec23+
         cb51411c4267d5b38275e0b9f2f150fd52d6f6dfbbf6805ded40368c852646127617b4+
         f6679dd911799378b9e7b9f8583c762996cfc95defd41216f777f55bccdf9bb78758e6+
         9e753e2e345d2b79e9cb6ae9f6f4f56921c4fb1fbfcf18b307429b7e929cf3d0d95063+
         895297233dddb02f823b2a953ac42174c603921f1d78f0bad55288b507ec99fb33acd9+
         7d6622ef453a2efb2b63bd7a67dd2aedece10bc73a0abd132a5be55677d76934fd689a+
         31961a49b55a1931fba8da4e99bcdaa4585451f63ad89cf36ffef10d63acfd25bc892b+
         89958dfae689b3c49ecd89509759ca7d9bab3b46388780ba86b4d43b111cc62ea9db9f+
         dfdeddddcde6b292de3f7a25ba9259493d4cd53d9fdfccc77e1bebf8e3e572f9a05bb4+
         7fa3a616ffb1b8b6be663fae542ad39f4d1ff4cdbb54a9546edfbb3df9f964f71f6cb9+
         5c2e168bbbbbbbdf18df1c6ea32fcc1707fd11e7d368faa1552a95eedf6ae4ea48dd33+
         f6afd36ac7e27f8c77ffe6b2119f09edf53fe5adfc69affc575b236e0b9d0bad7fd779+
         e931bb815a2a95221fb51b3cac35756daad5a266ebb97567b0debed6a19b373c04ce79+
         a958e23edea672ad8ea228760b223a1c6d35171ff9a8dd9c505d8fbd1bf6a731fec9f8+
         c2f70b6cfff94a08d165a7a0b055b02ccb9ebaace534889aeed8d243afd7bc6a833884+
         9aa631c6f29bb23a48aaa2b69a9453fabb2d5b090683d927d9a6c3128d0a5b85a65b4c+
         de4ad6fde1171f2dcaab20e17dbcfdd45f1b2b8f568c0da3ae86e6ee9fef669f4859eb+
         60e9e1d2ccc519b6bf1fd1fd54aa36a07950f12f15f145bd7637c0999c709da66a66c1+
         6cda9399bcd4d5b5700715be10aeebdbd8c44e9343bbbc0a81f276f99714c74587a3d1+
         e1a8f9d25c7fba1e3a178a0e4725adf763731a08362184eb37c3eb65f4973249557c5d+
         acbb60c22129f91337261a47f9cc97e6fc97f38d2f5e7ab824eb0ebe7d2e1c60f533fa+
         f4f5690f5667ab6b319eb405118f790887ce0eb559e8c175a55269f1fea273265c7fba+
         3e7163c2b2ac36fda5901e9271a19daaa8aa5f25bf53ef419dcccad2631ec2f858dcc5+
         f5055bad4991bc95b40763eafa8db14bb1c5fb8bed7b2c935727d7726b6eeda14355d5+
         4c2ed34de55a4ff17861e21e71cc43288458ceb9769e69d55149dd4bd5f56a0e64e9e1+
         925374e216b55fe57dfca4b5eb8ea8631e42ce39f3ae357a786b7f5b1bfadd50e7d775+
         cd8e9f67b740855f827ec943d94221b96b46b925ffcffcdc83b9e2eb22636cf483d1a6+
         43acdd13427453c00dbde0addddd5dea7d90ebadb36fed3e3fe6bf6353a3d746477f33+
         7a88ab8dc063c7bc39ca98dc3b72f632dec78f4a2be0843b0121dca2de0122cbdf2d9b+
         6687152ea0179c80105ea0de0122212d8495e78f84e31fc2d0e913da249377330f70d7+
         f11f9801e871c7ff4c08d0e31042006208210031841080184208400c21042086100210+
         43080188218400c41042006208210031841080184208400c2104208610021043080188+
         218400c41042006208210031841080184208400c2104208610021043080188218400c4+
         1042006208210031841080184208400c2104208610021043080188218400c410420062+
         08210031841080184208400c2104208610021043080188218400c41042006208210031+
         841080184208400c2104208610021043080188218400c4104200620821003184108018+
         4208400c2104208610021043080188218400c41042006208210031841080184208400c+
         2104208610021043080188218400c41042006208210031841080184208400c21042086+
         100210fb1f17e776dcedd91c0e0000000049454e44ae426082';


// len = base64_decode( %addr(chr64:*data): %len(chr64)
//                    : %addr(chr64Out:*data): %len(chr64Out:*MAX));

//
//  the IBM cvtch() routine converts chars like '0102FF' to the 
//  binary data equivalent x'0102FF'.
//
//  Note: cvtch() requires the hex data to be in uppercase (so FF not ff)

%len(Chr64Out) = %len(Chr64Out:*MAX);
ucChr64 = %xlate('abcdef': 'ABCDEF': chr64);
cvtch( %addr(chr64Out:*data)
     : %addr(ucChr64:*data)
     : %len(ucChr64) );
%len(chr64Out) = %div(%len(ucChr64) : 2);

unlink(pngFile);

fd = open( pngFile
         : O_CREAT + O_EXCL + O_WRONLY + O_INHERITMODE
         : 0 );

callp write(fd: %addr(Chr64Out:*DATA): %len(Chr64Out));
callp close(fd);

*inlr = *on;
gmalchow
Posts: 8
Joined: Fri Aug 30, 2024 8:40 pm

Re: Help with Base64 Encoded image

Post by gmalchow »

Hi Scott,
Thanks for the warm welcome back. It has been a while since I've participated. I'm glad I did. I really appreciate your help. Your solution solved my problem.

I came to the conclusion that the data was base64 encoded because I couldn't get cvtch to work. This was the first time I've ever tried using it. I wasn't aware of the capitalization requirement and I am guessing that is why I couldn't get it to work.

Thank you for the explanation as well. My naked eye never would have picked up the nuisances. I've used base64 encoding and decoding quite a bit, but I never thought about what it is actually doing.

Thanks again for everything.

Grizz
Post Reply