class static */
| 1439 | // do insert a linefeed character as a newline for every 76 characters of encoded output. |
| 1440 | |
| 1441 | /* class static */ void |
| 1442 | XMPUtils::EncodeToBase64 ( XMP_StringPtr rawStr, |
| 1443 | XMP_StringLen rawLen, |
| 1444 | XMP_StringPtr * encodedStr, |
| 1445 | XMP_StringLen * encodedLen ) |
| 1446 | { |
| 1447 | if ( (rawStr == 0) && (rawLen != 0) ) XMP_Throw ( "Null raw data buffer", kXMPErr_BadParam ); |
| 1448 | if ( rawLen == 0 ) { |
| 1449 | *encodedStr = 0; |
| 1450 | *encodedLen = 0; |
| 1451 | return; |
| 1452 | } |
| 1453 | |
| 1454 | char encChunk[4]; |
| 1455 | |
| 1456 | unsigned long in, out; |
| 1457 | unsigned char c1, c2, c3; |
| 1458 | unsigned long merge; |
| 1459 | |
| 1460 | const size_t outputSize = (rawLen / 3) * 4; // Approximate, might be small. |
| 1461 | |
| 1462 | sBase64Str->erase(); |
| 1463 | sBase64Str->reserve ( outputSize ); |
| 1464 | |
| 1465 | // ---------------------------------------------------------------------------------------- |
| 1466 | // Each 6 bits of input produces 8 bits of output, so 3 input bytes become 4 output bytes. |
| 1467 | // Process the whole chunks of 3 bytes first, then deal with any remainder. Be careful with |
| 1468 | // the loop comparison, size-2 could be negative! |
| 1469 | |
| 1470 | for ( in = 0, out = 0; (in+2) < rawLen; in += 3, out += 4 ) { |
| 1471 | |
| 1472 | c1 = rawStr[in]; |
| 1473 | c2 = rawStr[in+1]; |
| 1474 | c3 = rawStr[in+2]; |
| 1475 | |
| 1476 | merge = (c1 << 16) + (c2 << 8) + c3; |
| 1477 | |
| 1478 | encChunk[0] = sBase64Chars [ merge >> 18 ]; |
| 1479 | encChunk[1] = sBase64Chars [ (merge >> 12) & 0x3F ]; |
| 1480 | encChunk[2] = sBase64Chars [ (merge >> 6) & 0x3F ]; |
| 1481 | encChunk[3] = sBase64Chars [ merge & 0x3F ]; |
| 1482 | |
| 1483 | if ( out >= 76 ) { |
| 1484 | sBase64Str->append ( 1, kLF ); |
| 1485 | out = 0; |
| 1486 | } |
| 1487 | sBase64Str->append ( encChunk, 4 ); |
| 1488 | |
| 1489 | } |
| 1490 | |
| 1491 | // ------------------------------------------------------------------------------------------ |
| 1492 | // The output must always be a multiple of 4 bytes. If there is a 1 or 2 byte input remainder |
| 1493 | // we need to create another chunk. Zero pad with bits to a 6 bit multiple, then add one or |
| 1494 | // two '=' characters to pad out to 4 bytes. |
| 1495 | |
| 1496 | switch ( rawLen - in ) { |
| 1497 | |
| 1498 | case 0: // Done, no remainder. |