< prev index next >

src/java.desktop/share/native/liblcms/cmspack.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2017 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 104 #define ANYCHANNELS     CHANNELS_SH(15)
 105 #define ANYEXTRA        EXTRA_SH(7)
 106 #define ANYPLANAR       PLANAR_SH(1)
 107 #define ANYENDIAN       ENDIAN16_SH(1)
 108 #define ANYSWAP         DOSWAP_SH(1)
 109 #define ANYSWAPFIRST    SWAPFIRST_SH(1)
 110 #define ANYFLAVOR       FLAVOR_SH(1)
 111 
 112 
 113 // Suppress waning about info never being used
 114 
 115 #ifdef _MSC_VER
 116 #pragma warning(disable : 4100)
 117 #endif
 118 
 119 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
 120 
 121 
 122 // Does almost everything but is slow
 123 static
 124 cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
 125                                   register cmsUInt16Number wIn[],
 126                                   register cmsUInt8Number* accum,
 127                                   register cmsUInt32Number Stride)
 128 {
 129     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
 130     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
 131     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
 132     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
 133     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
 134     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
 135     cmsUInt16Number v;
 136     cmsUInt32Number i;
 137 
 138     if (ExtraFirst) {
 139         accum += Extra;
 140     }
 141 
 142     for (i=0; i < nChan; i++) {
 143         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 144 
 145         v = FROM_8_TO_16(*accum);
 146         v = Reverse ? REVERSE_FLAVOR_16(v) : v;
 147         wIn[index] = v;


 151     if (!ExtraFirst) {
 152         accum += Extra;
 153     }
 154 
 155     if (Extra == 0 && SwapFirst) {
 156         cmsUInt16Number tmp = wIn[0];
 157 
 158         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
 159         wIn[nChan-1] = tmp;
 160     }
 161 
 162     return accum;
 163 
 164     cmsUNUSED_PARAMETER(info);
 165     cmsUNUSED_PARAMETER(Stride);
 166 
 167 }
 168 
 169 // Extra channels are just ignored because come in the next planes
 170 static
 171 cmsUInt8Number* UnrollPlanarBytes(register _cmsTRANSFORM* info,
 172                                   register cmsUInt16Number wIn[],
 173                                   register cmsUInt8Number* accum,
 174                                   register cmsUInt32Number Stride)
 175 {
 176     cmsUInt32Number nChan     = T_CHANNELS(info -> InputFormat);
 177     cmsUInt32Number DoSwap    = T_DOSWAP(info ->InputFormat);
 178     cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat);
 179     cmsUInt32Number Reverse   = T_FLAVOR(info ->InputFormat);
 180     cmsUInt32Number i;
 181     cmsUInt8Number* Init = accum;
 182 
 183     if (DoSwap ^ SwapFirst) {
 184         accum += T_EXTRA(info -> InputFormat) * Stride;
 185     }
 186 
 187     for (i=0; i < nChan; i++) {
 188 
 189         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 190         cmsUInt16Number v = FROM_8_TO_16(*accum);
 191 
 192         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 193         accum += Stride;
 194     }
 195 
 196     return (Init + 1);
 197 }
 198 
 199 // Special cases, provided for performance
 200 static
 201 cmsUInt8Number* Unroll4Bytes(register _cmsTRANSFORM* info,
 202                              register cmsUInt16Number wIn[],
 203                              register cmsUInt8Number* accum,
 204                              register cmsUInt32Number Stride)
 205 {
 206     wIn[0] = FROM_8_TO_16(*accum); accum++; // C
 207     wIn[1] = FROM_8_TO_16(*accum); accum++; // M
 208     wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
 209     wIn[3] = FROM_8_TO_16(*accum); accum++; // K
 210 
 211     return accum;
 212 
 213     cmsUNUSED_PARAMETER(info);
 214     cmsUNUSED_PARAMETER(Stride);
 215 }
 216 
 217 static
 218 cmsUInt8Number* Unroll4BytesReverse(register _cmsTRANSFORM* info,
 219                                     register cmsUInt16Number wIn[],
 220                                     register cmsUInt8Number* accum,
 221                                     register cmsUInt32Number Stride)
 222 {
 223     wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
 224     wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
 225     wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
 226     wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
 227 
 228     return accum;
 229 
 230     cmsUNUSED_PARAMETER(info);
 231     cmsUNUSED_PARAMETER(Stride);
 232 }
 233 
 234 static
 235 cmsUInt8Number* Unroll4BytesSwapFirst(register _cmsTRANSFORM* info,
 236                                       register cmsUInt16Number wIn[],
 237                                       register cmsUInt8Number* accum,
 238                                       register cmsUInt32Number Stride)
 239 {
 240     wIn[3] = FROM_8_TO_16(*accum); accum++; // K
 241     wIn[0] = FROM_8_TO_16(*accum); accum++; // C
 242     wIn[1] = FROM_8_TO_16(*accum); accum++; // M
 243     wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
 244 
 245     return accum;
 246 
 247     cmsUNUSED_PARAMETER(info);
 248     cmsUNUSED_PARAMETER(Stride);
 249 }
 250 
 251 // KYMC
 252 static
 253 cmsUInt8Number* Unroll4BytesSwap(register _cmsTRANSFORM* info,
 254                                  register cmsUInt16Number wIn[],
 255                                  register cmsUInt8Number* accum,
 256                                  register cmsUInt32Number Stride)
 257 {
 258     wIn[3] = FROM_8_TO_16(*accum); accum++;  // K
 259     wIn[2] = FROM_8_TO_16(*accum); accum++;  // Y
 260     wIn[1] = FROM_8_TO_16(*accum); accum++;  // M
 261     wIn[0] = FROM_8_TO_16(*accum); accum++;  // C
 262 
 263     return accum;
 264 
 265     cmsUNUSED_PARAMETER(info);
 266     cmsUNUSED_PARAMETER(Stride);
 267 }
 268 
 269 static
 270 cmsUInt8Number* Unroll4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
 271                                           register cmsUInt16Number wIn[],
 272                                           register cmsUInt8Number* accum,
 273                                           register cmsUInt32Number Stride)
 274 {
 275     wIn[2] = FROM_8_TO_16(*accum); accum++;  // K
 276     wIn[1] = FROM_8_TO_16(*accum); accum++;  // Y
 277     wIn[0] = FROM_8_TO_16(*accum); accum++;  // M
 278     wIn[3] = FROM_8_TO_16(*accum); accum++;  // C
 279 
 280     return accum;
 281 
 282     cmsUNUSED_PARAMETER(info);
 283     cmsUNUSED_PARAMETER(Stride);
 284 }
 285 
 286 static
 287 cmsUInt8Number* Unroll3Bytes(register _cmsTRANSFORM* info,
 288                              register cmsUInt16Number wIn[],
 289                              register cmsUInt8Number* accum,
 290                              register cmsUInt32Number Stride)
 291 {
 292     wIn[0] = FROM_8_TO_16(*accum); accum++;     // R
 293     wIn[1] = FROM_8_TO_16(*accum); accum++;     // G
 294     wIn[2] = FROM_8_TO_16(*accum); accum++;     // B
 295 
 296     return accum;
 297 
 298     cmsUNUSED_PARAMETER(info);
 299     cmsUNUSED_PARAMETER(Stride);
 300 }
 301 
 302 static
 303 cmsUInt8Number* Unroll3BytesSkip1Swap(register _cmsTRANSFORM* info,
 304                                       register cmsUInt16Number wIn[],
 305                                       register cmsUInt8Number* accum,
 306                                       register cmsUInt32Number Stride)
 307 {
 308     accum++; // A
 309     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 310     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 311     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 312 
 313     return accum;
 314 
 315     cmsUNUSED_PARAMETER(info);
 316     cmsUNUSED_PARAMETER(Stride);
 317 }
 318 
 319 static
 320 cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
 321                                               register cmsUInt16Number wIn[],
 322                                               register cmsUInt8Number* accum,
 323                                               register cmsUInt32Number Stride)
 324 {
 325     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 326     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 327     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 328     accum++; // A
 329 
 330     return accum;
 331 
 332     cmsUNUSED_PARAMETER(info);
 333     cmsUNUSED_PARAMETER(Stride);
 334 }
 335 
 336 static
 337 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info,
 338                                            register cmsUInt16Number wIn[],
 339                                            register cmsUInt8Number* accum,
 340                                            register cmsUInt32Number Stride)
 341 {
 342     accum++; // A
 343     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 344     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 345     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 346 
 347     return accum;
 348 
 349     cmsUNUSED_PARAMETER(info);
 350     cmsUNUSED_PARAMETER(Stride);
 351 }
 352 
 353 
 354 // BRG
 355 static
 356 cmsUInt8Number* Unroll3BytesSwap(register _cmsTRANSFORM* info,
 357                                  register cmsUInt16Number wIn[],
 358                                  register cmsUInt8Number* accum,
 359                                  register cmsUInt32Number Stride)
 360 {
 361     wIn[2] = FROM_8_TO_16(*accum); accum++;     // B
 362     wIn[1] = FROM_8_TO_16(*accum); accum++;     // G
 363     wIn[0] = FROM_8_TO_16(*accum); accum++;     // R
 364 
 365     return accum;
 366 
 367     cmsUNUSED_PARAMETER(info);
 368     cmsUNUSED_PARAMETER(Stride);
 369 }
 370 
 371 static
 372 cmsUInt8Number* UnrollLabV2_8(register _cmsTRANSFORM* info,
 373                               register cmsUInt16Number wIn[],
 374                               register cmsUInt8Number* accum,
 375                               register cmsUInt32Number Stride)
 376 {
 377     wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // L
 378     wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // a
 379     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 380 
 381     return accum;
 382 
 383     cmsUNUSED_PARAMETER(info);
 384     cmsUNUSED_PARAMETER(Stride);
 385 }
 386 
 387 static
 388 cmsUInt8Number* UnrollALabV2_8(register _cmsTRANSFORM* info,
 389                                register cmsUInt16Number wIn[],
 390                                register cmsUInt8Number* accum,
 391                                register cmsUInt32Number Stride)
 392 {
 393     accum++;  // A
 394     wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // L
 395     wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // a
 396     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 397 
 398     return accum;
 399 
 400     cmsUNUSED_PARAMETER(info);
 401     cmsUNUSED_PARAMETER(Stride);
 402 }
 403 
 404 static
 405 cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
 406                                register cmsUInt16Number wIn[],
 407                                register cmsUInt8Number* accum,
 408                                register cmsUInt32Number Stride)
 409 {
 410     wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // L
 411     wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // a
 412     wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // b
 413 
 414     return accum;
 415 
 416     cmsUNUSED_PARAMETER(info);
 417     cmsUNUSED_PARAMETER(Stride);
 418 }
 419 
 420 // for duplex
 421 static
 422 cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
 423                                      register cmsUInt16Number wIn[],
 424                                      register cmsUInt8Number* accum,
 425                                      register cmsUInt32Number Stride)
 426 {
 427     wIn[0] = FROM_8_TO_16(*accum); accum++;     // ch1
 428     wIn[1] = FROM_8_TO_16(*accum); accum++;     // ch2
 429 
 430     return accum;
 431 
 432     cmsUNUSED_PARAMETER(info);
 433     cmsUNUSED_PARAMETER(Stride);
 434 }
 435 
 436 
 437 
 438 
 439 // Monochrome duplicates L into RGB for null-transforms
 440 static
 441 cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
 442                             register cmsUInt16Number wIn[],
 443                             register cmsUInt8Number* accum,
 444                             register cmsUInt32Number Stride)
 445 {
 446     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 447 
 448     return accum;
 449 
 450     cmsUNUSED_PARAMETER(info);
 451     cmsUNUSED_PARAMETER(Stride);
 452 }
 453 
 454 
 455 static
 456 cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
 457                                  register cmsUInt16Number wIn[],
 458                                  register cmsUInt8Number* accum,
 459                                  register cmsUInt32Number Stride)
 460 {
 461     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 462     accum += 1;
 463 
 464     return accum;
 465 
 466     cmsUNUSED_PARAMETER(info);
 467     cmsUNUSED_PARAMETER(Stride);
 468 }
 469 
 470 static
 471 cmsUInt8Number* Unroll1ByteSkip2(register _cmsTRANSFORM* info,
 472                                  register cmsUInt16Number wIn[],
 473                                  register cmsUInt8Number* accum,
 474                                  register cmsUInt32Number Stride)
 475 {
 476     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 477     accum += 2;
 478 
 479     return accum;
 480 
 481     cmsUNUSED_PARAMETER(info);
 482     cmsUNUSED_PARAMETER(Stride);
 483 }
 484 
 485 static
 486 cmsUInt8Number* Unroll1ByteReversed(register _cmsTRANSFORM* info,
 487                                     register cmsUInt16Number wIn[],
 488                                     register cmsUInt8Number* accum,
 489                                     register cmsUInt32Number Stride)
 490 {
 491     wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++;     // L
 492 
 493     return accum;
 494 
 495     cmsUNUSED_PARAMETER(info);
 496     cmsUNUSED_PARAMETER(Stride);
 497 }
 498 
 499 
 500 static
 501 cmsUInt8Number* UnrollAnyWords(register _cmsTRANSFORM* info,
 502                                register cmsUInt16Number wIn[],
 503                                register cmsUInt8Number* accum,
 504                                register cmsUInt32Number Stride)
 505 {
 506    cmsUInt32Number nChan       = T_CHANNELS(info -> InputFormat);
 507    cmsUInt32Number SwapEndian  = T_ENDIAN16(info -> InputFormat);
 508    cmsUInt32Number DoSwap      = T_DOSWAP(info ->InputFormat);
 509    cmsUInt32Number Reverse     = T_FLAVOR(info ->InputFormat);
 510    cmsUInt32Number SwapFirst   = T_SWAPFIRST(info -> InputFormat);
 511    cmsUInt32Number Extra       = T_EXTRA(info -> InputFormat);
 512    cmsUInt32Number ExtraFirst  = DoSwap ^ SwapFirst;
 513    cmsUInt32Number i;
 514 
 515     if (ExtraFirst) {
 516         accum += Extra * sizeof(cmsUInt16Number);
 517     }
 518 
 519     for (i=0; i < nChan; i++) {
 520 
 521         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 522         cmsUInt16Number v = *(cmsUInt16Number*) accum;
 523 
 524         if (SwapEndian)


 530     }
 531 
 532     if (!ExtraFirst) {
 533         accum += Extra * sizeof(cmsUInt16Number);
 534     }
 535 
 536     if (Extra == 0 && SwapFirst) {
 537 
 538         cmsUInt16Number tmp = wIn[0];
 539 
 540         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
 541         wIn[nChan-1] = tmp;
 542     }
 543 
 544     return accum;
 545 
 546     cmsUNUSED_PARAMETER(Stride);
 547 }
 548 
 549 static
 550 cmsUInt8Number* UnrollPlanarWords(register _cmsTRANSFORM* info,
 551                                   register cmsUInt16Number wIn[],
 552                                   register cmsUInt8Number* accum,
 553                                   register cmsUInt32Number Stride)
 554 {
 555     cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
 556     cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
 557     cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
 558     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
 559     cmsUInt32Number i;
 560     cmsUInt8Number* Init = accum;
 561 
 562     if (DoSwap) {
 563         accum += T_EXTRA(info -> InputFormat) * Stride;
 564     }
 565 
 566     for (i=0; i < nChan; i++) {
 567 
 568         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 569         cmsUInt16Number v = *(cmsUInt16Number*) accum;
 570 
 571         if (SwapEndian)
 572             v = CHANGE_ENDIAN(v);
 573 
 574         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 575 
 576         accum +=  Stride;
 577     }
 578 
 579     return (Init + sizeof(cmsUInt16Number));
 580 }
 581 
 582 
 583 static
 584 cmsUInt8Number* Unroll4Words(register _cmsTRANSFORM* info,
 585                              register cmsUInt16Number wIn[],
 586                              register cmsUInt8Number* accum,
 587                              register cmsUInt32Number Stride)
 588 {
 589     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 590     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 591     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 592     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 593 
 594     return accum;
 595 
 596     cmsUNUSED_PARAMETER(info);
 597     cmsUNUSED_PARAMETER(Stride);
 598 }
 599 
 600 static
 601 cmsUInt8Number* Unroll4WordsReverse(register _cmsTRANSFORM* info,
 602                                     register cmsUInt16Number wIn[],
 603                                     register cmsUInt8Number* accum,
 604                                     register cmsUInt32Number Stride)
 605 {
 606     wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
 607     wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
 608     wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
 609     wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
 610 
 611     return accum;
 612 
 613     cmsUNUSED_PARAMETER(info);
 614     cmsUNUSED_PARAMETER(Stride);
 615 }
 616 
 617 static
 618 cmsUInt8Number* Unroll4WordsSwapFirst(register _cmsTRANSFORM* info,
 619                                       register cmsUInt16Number wIn[],
 620                                       register cmsUInt8Number* accum,
 621                                       register cmsUInt32Number Stride)
 622 {
 623     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 624     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 625     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 626     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 627 
 628     return accum;
 629 
 630     cmsUNUSED_PARAMETER(info);
 631     cmsUNUSED_PARAMETER(Stride);
 632 }
 633 
 634 // KYMC
 635 static
 636 cmsUInt8Number* Unroll4WordsSwap(register _cmsTRANSFORM* info,
 637                                  register cmsUInt16Number wIn[],
 638                                  register cmsUInt8Number* accum,
 639                                  register cmsUInt32Number Stride)
 640 {
 641     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 642     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 643     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 644     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 645 
 646     return accum;
 647 
 648     cmsUNUSED_PARAMETER(info);
 649     cmsUNUSED_PARAMETER(Stride);
 650 }
 651 
 652 static
 653 cmsUInt8Number* Unroll4WordsSwapSwapFirst(register _cmsTRANSFORM* info,
 654                                           register cmsUInt16Number wIn[],
 655                                           register cmsUInt8Number* accum,
 656                                           register cmsUInt32Number Stride)
 657 {
 658     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
 659     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 660     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
 661     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
 662 
 663     return accum;
 664 
 665     cmsUNUSED_PARAMETER(info);
 666     cmsUNUSED_PARAMETER(Stride);
 667 }
 668 
 669 static
 670 cmsUInt8Number* Unroll3Words(register _cmsTRANSFORM* info,
 671                              register cmsUInt16Number wIn[],
 672                              register cmsUInt8Number* accum,
 673                              register cmsUInt32Number Stride)
 674 {
 675     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2;  // C R
 676     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2;  // M G
 677     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;  // Y B
 678 
 679     return accum;
 680 
 681     cmsUNUSED_PARAMETER(info);
 682     cmsUNUSED_PARAMETER(Stride);
 683 }
 684 
 685 static
 686 cmsUInt8Number* Unroll3WordsSwap(register _cmsTRANSFORM* info,
 687                                  register cmsUInt16Number wIn[],
 688                                  register cmsUInt8Number* accum,
 689                                  register cmsUInt32Number Stride)
 690 {
 691     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;  // C R
 692     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2;  // M G
 693     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2;  // Y B
 694 
 695     return accum;
 696 
 697     cmsUNUSED_PARAMETER(info);
 698     cmsUNUSED_PARAMETER(Stride);
 699 }
 700 
 701 static
 702 cmsUInt8Number* Unroll3WordsSkip1Swap(register _cmsTRANSFORM* info,
 703                                       register cmsUInt16Number wIn[],
 704                                       register cmsUInt8Number* accum,
 705                                       register cmsUInt32Number Stride)
 706 {
 707     accum += 2; // A
 708     wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
 709     wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
 710     wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
 711 
 712     return accum;
 713 
 714     cmsUNUSED_PARAMETER(info);
 715     cmsUNUSED_PARAMETER(Stride);
 716 }
 717 
 718 static
 719 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(register _cmsTRANSFORM* info,
 720                                            register cmsUInt16Number wIn[],
 721                                            register cmsUInt8Number* accum,
 722                                            register cmsUInt32Number Stride)
 723 {
 724     accum += 2; // A
 725     wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
 726     wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
 727     wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
 728 
 729     return accum;
 730 
 731     cmsUNUSED_PARAMETER(info);
 732     cmsUNUSED_PARAMETER(Stride);
 733 }
 734 
 735 static
 736 cmsUInt8Number* Unroll1Word(register _cmsTRANSFORM* info,
 737                             register cmsUInt16Number wIn[],
 738                             register cmsUInt8Number* accum,
 739                             register cmsUInt32Number Stride)
 740 {
 741     wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;   // L
 742 
 743     return accum;
 744 
 745     cmsUNUSED_PARAMETER(info);
 746     cmsUNUSED_PARAMETER(Stride);
 747 }
 748 
 749 static
 750 cmsUInt8Number* Unroll1WordReversed(register _cmsTRANSFORM* info,
 751                                     register cmsUInt16Number wIn[],
 752                                     register cmsUInt8Number* accum,
 753                                     register cmsUInt32Number Stride)
 754 {
 755     wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
 756 
 757     return accum;
 758 
 759     cmsUNUSED_PARAMETER(info);
 760     cmsUNUSED_PARAMETER(Stride);
 761 }
 762 
 763 static
 764 cmsUInt8Number* Unroll1WordSkip3(register _cmsTRANSFORM* info,
 765                                  register cmsUInt16Number wIn[],
 766                                  register cmsUInt8Number* accum,
 767                                  register cmsUInt32Number Stride)
 768 {
 769     wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
 770 
 771     accum += 8;
 772 
 773     return accum;
 774 
 775     cmsUNUSED_PARAMETER(info);
 776     cmsUNUSED_PARAMETER(Stride);
 777 }
 778 
 779 static
 780 cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
 781                                      register cmsUInt16Number wIn[],
 782                                      register cmsUInt8Number* accum,
 783                                      register cmsUInt32Number Stride)
 784 {
 785     wIn[0] = *(cmsUInt16Number*) accum; accum += 2;    // ch1
 786     wIn[1] = *(cmsUInt16Number*) accum; accum += 2;    // ch2
 787 
 788     return accum;
 789 
 790     cmsUNUSED_PARAMETER(info);
 791     cmsUNUSED_PARAMETER(Stride);
 792 }
 793 
 794 
 795 // This is a conversion of Lab double to 16 bits
 796 static
 797 cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
 798                                     register cmsUInt16Number wIn[],
 799                                     register cmsUInt8Number* accum,
 800                                     register cmsUInt32Number  Stride)
 801 {
 802     if (T_PLANAR(info -> InputFormat)) {
 803 
 804         cmsCIELab Lab;
 805         cmsUInt8Number* pos_L;
 806         cmsUInt8Number* pos_a;
 807         cmsUInt8Number* pos_b;
 808 
 809         pos_L = accum;
 810         pos_a = accum + Stride;
 811         pos_b = accum + Stride * 2;
 812 
 813         Lab.L = *(cmsFloat64Number*) pos_L;
 814         Lab.a = *(cmsFloat64Number*) pos_a;
 815         Lab.b = *(cmsFloat64Number*) pos_b;
 816 
 817         cmsFloat2LabEncoded(wIn, &Lab);
 818         return accum + sizeof(cmsFloat64Number);
 819     }
 820     else {
 821 
 822         cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
 823         accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
 824         return accum;
 825     }
 826 }
 827 
 828 
 829 // This is a conversion of Lab float to 16 bits
 830 static
 831 cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
 832                                     register cmsUInt16Number wIn[],
 833                                     register cmsUInt8Number* accum,
 834                                     register cmsUInt32Number  Stride)
 835 {
 836     cmsCIELab Lab;
 837 
 838     if (T_PLANAR(info -> InputFormat)) {
 839 
 840         cmsUInt8Number* pos_L;
 841         cmsUInt8Number* pos_a;
 842         cmsUInt8Number* pos_b;
 843 
 844         pos_L = accum;
 845         pos_a = accum + Stride;
 846         pos_b = accum + Stride * 2;
 847 
 848         Lab.L = *(cmsFloat32Number*)pos_L;
 849         Lab.a = *(cmsFloat32Number*)pos_a;
 850         Lab.b = *(cmsFloat32Number*)pos_b;
 851 
 852         cmsFloat2LabEncoded(wIn, &Lab);
 853         return accum + sizeof(cmsFloat32Number);
 854     }
 855     else {
 856 
 857         Lab.L = ((cmsFloat32Number*) accum)[0];
 858         Lab.a = ((cmsFloat32Number*) accum)[1];
 859         Lab.b = ((cmsFloat32Number*) accum)[2];
 860 
 861         cmsFloat2LabEncoded(wIn, &Lab);
 862         accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
 863         return accum;
 864     }
 865 }
 866 
 867 // This is a conversion of XYZ double to 16 bits
 868 static
 869 cmsUInt8Number* UnrollXYZDoubleTo16(register _cmsTRANSFORM* info,
 870                                     register cmsUInt16Number wIn[],
 871                                     register cmsUInt8Number* accum,
 872                                     register cmsUInt32Number Stride)
 873 {
 874     if (T_PLANAR(info -> InputFormat)) {
 875 
 876         cmsCIEXYZ XYZ;
 877         cmsUInt8Number* pos_X;
 878         cmsUInt8Number* pos_Y;
 879         cmsUInt8Number* pos_Z;
 880 
 881         pos_X = accum;
 882         pos_Y = accum + Stride;
 883         pos_Z = accum + Stride * 2;
 884 
 885         XYZ.X = *(cmsFloat64Number*)pos_X;
 886         XYZ.Y = *(cmsFloat64Number*)pos_Y;
 887         XYZ.Z = *(cmsFloat64Number*)pos_Z;
 888 
 889         cmsFloat2XYZEncoded(wIn, &XYZ);
 890 
 891         return accum + sizeof(cmsFloat64Number);
 892 
 893     }
 894 
 895     else {
 896         cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
 897         accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
 898 
 899         return accum;
 900     }
 901 }
 902 
 903 // This is a conversion of XYZ float to 16 bits
 904 static
 905 cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
 906                                    register cmsUInt16Number wIn[],
 907                                    register cmsUInt8Number* accum,
 908                                    register cmsUInt32Number Stride)
 909 {
 910     if (T_PLANAR(info -> InputFormat)) {
 911 
 912         cmsCIEXYZ XYZ;
 913         cmsUInt8Number* pos_X;
 914         cmsUInt8Number* pos_Y;
 915         cmsUInt8Number* pos_Z;
 916 
 917         pos_X = accum;
 918         pos_Y = accum + Stride;
 919         pos_Z = accum + Stride * 2;
 920 
 921         XYZ.X = *(cmsFloat32Number*)pos_X;
 922         XYZ.Y = *(cmsFloat32Number*)pos_Y;
 923         XYZ.Z = *(cmsFloat32Number*)pos_Z;
 924 
 925         cmsFloat2XYZEncoded(wIn, &XYZ);
 926 
 927         return accum + sizeof(cmsFloat32Number);
 928 


 965      default: return FALSE;
 966     }
 967 }
 968 
 969 // Return the size in bytes of a given formatter
 970 static
 971 cmsUInt32Number PixelSize(cmsUInt32Number Format)
 972 {
 973     cmsUInt32Number fmt_bytes = T_BYTES(Format);
 974 
 975     // For double, the T_BYTES field is zero
 976     if (fmt_bytes == 0)
 977         return sizeof(cmsUInt64Number);
 978 
 979     // Otherwise, it is already correct for all formats
 980     return fmt_bytes;
 981 }
 982 
 983 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
 984 static
 985 cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
 986                                 register cmsUInt16Number wIn[],
 987                                 register cmsUInt8Number* accum,
 988                                 register cmsUInt32Number Stride)
 989 {
 990 
 991     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
 992     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
 993     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
 994     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
 995     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
 996     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
 997     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
 998     cmsFloat64Number v;
 999     cmsUInt16Number  vi;
1000     cmsUInt32Number i, start = 0;
1001     cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1002 
1003 
1004     Stride /= PixelSize(info->InputFormat);
1005 
1006     if (ExtraFirst)
1007             start = Extra;
1008 


1023         wIn[index] = vi;
1024     }
1025 
1026 
1027     if (Extra == 0 && SwapFirst) {
1028         cmsUInt16Number tmp = wIn[0];
1029 
1030         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1031         wIn[nChan-1] = tmp;
1032     }
1033 
1034     if (T_PLANAR(info -> InputFormat))
1035         return accum + sizeof(cmsFloat64Number);
1036     else
1037         return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1038 }
1039 
1040 
1041 
1042 static
1043 cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
1044                                 register cmsUInt16Number wIn[],
1045                                 register cmsUInt8Number* accum,
1046                                 register cmsUInt32Number Stride)
1047 {
1048 
1049     cmsUInt32Number nChan  = T_CHANNELS(info -> InputFormat);
1050     cmsUInt32Number DoSwap   = T_DOSWAP(info ->InputFormat);
1051     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
1052     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
1053     cmsUInt32Number Extra   = T_EXTRA(info -> InputFormat);
1054     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1055     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
1056     cmsFloat32Number v;
1057     cmsUInt16Number  vi;
1058     cmsUInt32Number i, start = 0;
1059     cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1060 
1061     Stride /= PixelSize(info->InputFormat);
1062 
1063     if (ExtraFirst)
1064             start = Extra;
1065 
1066     for (i=0; i < nChan; i++) {


1082 
1083 
1084     if (Extra == 0 && SwapFirst) {
1085         cmsUInt16Number tmp = wIn[0];
1086 
1087         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1088         wIn[nChan-1] = tmp;
1089     }
1090 
1091     if (T_PLANAR(info -> InputFormat))
1092         return accum + sizeof(cmsFloat32Number);
1093     else
1094         return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1095 }
1096 
1097 
1098 
1099 
1100 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1101 static
1102 cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
1103                                   register cmsUInt16Number wIn[],
1104                                   register cmsUInt8Number* accum,
1105                                   register cmsUInt32Number Stride)
1106 {
1107     cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1108 
1109     wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1110 
1111     return accum + sizeof(cmsFloat64Number);
1112 
1113     cmsUNUSED_PARAMETER(info);
1114     cmsUNUSED_PARAMETER(Stride);
1115 }
1116 
1117 //-------------------------------------------------------------------------------------------------------------------
1118 
1119 // For anything going from cmsFloat32Number
1120 static
1121 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1122                                     cmsFloat32Number wIn[],
1123                                     cmsUInt8Number* accum,
1124                                     cmsUInt32Number Stride)
1125 {


1335     }
1336     else {
1337 
1338         wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1339         wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1340         wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1341 
1342         accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1343         return accum;
1344     }
1345 }
1346 
1347 
1348 
1349 // Packing routines -----------------------------------------------------------------------------------------------------------
1350 
1351 
1352 // Generic chunky for byte
1353 
1354 static
1355 cmsUInt8Number* PackAnyBytes(register _cmsTRANSFORM* info,
1356                              register cmsUInt16Number wOut[],
1357                              register cmsUInt8Number* output,
1358                              register cmsUInt32Number Stride)
1359 {
1360     cmsUInt32Number nChan  = T_CHANNELS(info -> OutputFormat);
1361     cmsUInt32Number DoSwap   = T_DOSWAP(info ->OutputFormat);
1362     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1363     cmsUInt32Number Extra   = T_EXTRA(info -> OutputFormat);
1364     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
1365     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1366     cmsUInt8Number* swap1;
1367     cmsUInt8Number v = 0;
1368     cmsUInt32Number i;
1369 
1370     swap1 = output;
1371 
1372     if (ExtraFirst) {
1373         output += Extra;
1374     }
1375 
1376     for (i=0; i < nChan; i++) {
1377 
1378         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;


1387 
1388     if (!ExtraFirst) {
1389         output += Extra;
1390     }
1391 
1392     if (Extra == 0 && SwapFirst) {
1393 
1394         memmove(swap1 + 1, swap1, nChan-1);
1395         *swap1 = v;
1396     }
1397 
1398 
1399     return output;
1400 
1401     cmsUNUSED_PARAMETER(Stride);
1402 }
1403 
1404 
1405 
1406 static
1407 cmsUInt8Number* PackAnyWords(register _cmsTRANSFORM* info,
1408                              register cmsUInt16Number wOut[],
1409                              register cmsUInt8Number* output,
1410                              register cmsUInt32Number Stride)
1411 {
1412     cmsUInt32Number nChan  = T_CHANNELS(info -> OutputFormat);
1413     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
1414     cmsUInt32Number DoSwap   = T_DOSWAP(info ->OutputFormat);
1415     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1416     cmsUInt32Number Extra   = T_EXTRA(info -> OutputFormat);
1417     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
1418     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1419     cmsUInt16Number* swap1;
1420     cmsUInt16Number v = 0;
1421     cmsUInt32Number i;
1422 
1423     swap1 = (cmsUInt16Number*) output;
1424 
1425     if (ExtraFirst) {
1426         output += Extra * sizeof(cmsUInt16Number);
1427     }
1428 
1429     for (i=0; i < nChan; i++) {
1430 


1444     }
1445 
1446     if (!ExtraFirst) {
1447         output += Extra * sizeof(cmsUInt16Number);
1448     }
1449 
1450     if (Extra == 0 && SwapFirst) {
1451 
1452         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1453         *swap1 = v;
1454     }
1455 
1456 
1457     return output;
1458 
1459     cmsUNUSED_PARAMETER(Stride);
1460 }
1461 
1462 
1463 static
1464 cmsUInt8Number* PackPlanarBytes(register _cmsTRANSFORM* info,
1465                                 register cmsUInt16Number wOut[],
1466                                 register cmsUInt8Number* output,
1467                                 register cmsUInt32Number Stride)
1468 {
1469     cmsUInt32Number nChan     = T_CHANNELS(info -> OutputFormat);
1470     cmsUInt32Number DoSwap    = T_DOSWAP(info ->OutputFormat);
1471     cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1472     cmsUInt32Number Reverse   = T_FLAVOR(info ->OutputFormat);
1473     cmsUInt32Number i;
1474     cmsUInt8Number* Init = output;
1475 
1476 
1477     if (DoSwap ^ SwapFirst) {
1478         output += T_EXTRA(info -> OutputFormat) * Stride;
1479     }
1480 
1481 
1482     for (i=0; i < nChan; i++) {
1483 
1484         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1485         cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1486 
1487         *(cmsUInt8Number*)  output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1488         output += Stride;
1489     }
1490 
1491     return (Init + 1);
1492 
1493     cmsUNUSED_PARAMETER(Stride);
1494 }
1495 
1496 
1497 static
1498 cmsUInt8Number* PackPlanarWords(register _cmsTRANSFORM* info,
1499                                 register cmsUInt16Number wOut[],
1500                                 register cmsUInt8Number* output,
1501                                 register cmsUInt32Number Stride)
1502 {
1503     cmsUInt32Number nChan      = T_CHANNELS(info -> OutputFormat);
1504     cmsUInt32Number DoSwap     = T_DOSWAP(info ->OutputFormat);
1505     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1506     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
1507     cmsUInt32Number i;
1508     cmsUInt8Number* Init = output;
1509     cmsUInt16Number v;
1510 
1511     if (DoSwap) {
1512         output += T_EXTRA(info -> OutputFormat) * Stride;
1513     }
1514 
1515     for (i=0; i < nChan; i++) {
1516 
1517         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1518 
1519         v = wOut[index];
1520 
1521         if (SwapEndian)
1522             v = CHANGE_ENDIAN(v);
1523 
1524         if (Reverse)
1525             v =  REVERSE_FLAVOR_16(v);
1526 
1527         *(cmsUInt16Number*) output = v;
1528         output += Stride;
1529     }
1530 
1531     return (Init + sizeof(cmsUInt16Number));
1532 }
1533 
1534 // CMYKcm (unrolled for speed)
1535 
1536 static
1537 cmsUInt8Number* Pack6Bytes(register _cmsTRANSFORM* info,
1538                            register cmsUInt16Number wOut[],
1539                            register cmsUInt8Number* output,
1540                            register cmsUInt32Number Stride)
1541 {
1542     *output++ = FROM_16_TO_8(wOut[0]);
1543     *output++ = FROM_16_TO_8(wOut[1]);
1544     *output++ = FROM_16_TO_8(wOut[2]);
1545     *output++ = FROM_16_TO_8(wOut[3]);
1546     *output++ = FROM_16_TO_8(wOut[4]);
1547     *output++ = FROM_16_TO_8(wOut[5]);
1548 
1549     return output;
1550 
1551     cmsUNUSED_PARAMETER(info);
1552     cmsUNUSED_PARAMETER(Stride);
1553 }
1554 
1555 // KCMYcm
1556 
1557 static
1558 cmsUInt8Number* Pack6BytesSwap(register _cmsTRANSFORM* info,
1559                                register cmsUInt16Number wOut[],
1560                                register cmsUInt8Number* output,
1561                                register cmsUInt32Number Stride)
1562 {
1563     *output++ = FROM_16_TO_8(wOut[5]);
1564     *output++ = FROM_16_TO_8(wOut[4]);
1565     *output++ = FROM_16_TO_8(wOut[3]);
1566     *output++ = FROM_16_TO_8(wOut[2]);
1567     *output++ = FROM_16_TO_8(wOut[1]);
1568     *output++ = FROM_16_TO_8(wOut[0]);
1569 
1570     return output;
1571 
1572     cmsUNUSED_PARAMETER(info);
1573     cmsUNUSED_PARAMETER(Stride);
1574 }
1575 
1576 // CMYKcm
1577 static
1578 cmsUInt8Number* Pack6Words(register _cmsTRANSFORM* info,
1579                            register cmsUInt16Number wOut[],
1580                            register cmsUInt8Number* output,
1581                            register cmsUInt32Number Stride)
1582 {
1583     *(cmsUInt16Number*) output = wOut[0];
1584     output+= 2;
1585     *(cmsUInt16Number*) output = wOut[1];
1586     output+= 2;
1587     *(cmsUInt16Number*) output = wOut[2];
1588     output+= 2;
1589     *(cmsUInt16Number*) output = wOut[3];
1590     output+= 2;
1591     *(cmsUInt16Number*) output = wOut[4];
1592     output+= 2;
1593     *(cmsUInt16Number*) output = wOut[5];
1594     output+= 2;
1595 
1596     return output;
1597 
1598     cmsUNUSED_PARAMETER(info);
1599     cmsUNUSED_PARAMETER(Stride);
1600 }
1601 
1602 // KCMYcm
1603 static
1604 cmsUInt8Number* Pack6WordsSwap(register _cmsTRANSFORM* info,
1605                                register cmsUInt16Number wOut[],
1606                                register cmsUInt8Number* output,
1607                                register cmsUInt32Number Stride)
1608 {
1609     *(cmsUInt16Number*) output = wOut[5];
1610     output+= 2;
1611     *(cmsUInt16Number*) output = wOut[4];
1612     output+= 2;
1613     *(cmsUInt16Number*) output = wOut[3];
1614     output+= 2;
1615     *(cmsUInt16Number*) output = wOut[2];
1616     output+= 2;
1617     *(cmsUInt16Number*) output = wOut[1];
1618     output+= 2;
1619     *(cmsUInt16Number*) output = wOut[0];
1620     output+= 2;
1621 
1622     return output;
1623 
1624     cmsUNUSED_PARAMETER(info);
1625     cmsUNUSED_PARAMETER(Stride);
1626 }
1627 
1628 
1629 static
1630 cmsUInt8Number* Pack4Bytes(register _cmsTRANSFORM* info,
1631                            register cmsUInt16Number wOut[],
1632                            register cmsUInt8Number* output,
1633                            register cmsUInt32Number Stride)
1634 {
1635     *output++ = FROM_16_TO_8(wOut[0]);
1636     *output++ = FROM_16_TO_8(wOut[1]);
1637     *output++ = FROM_16_TO_8(wOut[2]);
1638     *output++ = FROM_16_TO_8(wOut[3]);
1639 
1640     return output;
1641 
1642     cmsUNUSED_PARAMETER(info);
1643     cmsUNUSED_PARAMETER(Stride);
1644 }
1645 
1646 static
1647 cmsUInt8Number* Pack4BytesReverse(register _cmsTRANSFORM* info,
1648                                   register cmsUInt16Number wOut[],
1649                                   register cmsUInt8Number* output,
1650                                   register cmsUInt32Number Stride)
1651 {
1652     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1653     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1654     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1655     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1656 
1657     return output;
1658 
1659     cmsUNUSED_PARAMETER(info);
1660     cmsUNUSED_PARAMETER(Stride);
1661 }
1662 
1663 
1664 static
1665 cmsUInt8Number* Pack4BytesSwapFirst(register _cmsTRANSFORM* info,
1666                                     register cmsUInt16Number wOut[],
1667                                     register cmsUInt8Number* output,
1668                                     register cmsUInt32Number Stride)
1669 {
1670     *output++ = FROM_16_TO_8(wOut[3]);
1671     *output++ = FROM_16_TO_8(wOut[0]);
1672     *output++ = FROM_16_TO_8(wOut[1]);
1673     *output++ = FROM_16_TO_8(wOut[2]);
1674 
1675     return output;
1676 
1677     cmsUNUSED_PARAMETER(info);
1678     cmsUNUSED_PARAMETER(Stride);
1679 }
1680 
1681 // ABGR
1682 static
1683 cmsUInt8Number* Pack4BytesSwap(register _cmsTRANSFORM* info,
1684                                register cmsUInt16Number wOut[],
1685                                register cmsUInt8Number* output,
1686                                register cmsUInt32Number Stride)
1687 {
1688     *output++ = FROM_16_TO_8(wOut[3]);
1689     *output++ = FROM_16_TO_8(wOut[2]);
1690     *output++ = FROM_16_TO_8(wOut[1]);
1691     *output++ = FROM_16_TO_8(wOut[0]);
1692 
1693     return output;
1694 
1695     cmsUNUSED_PARAMETER(info);
1696     cmsUNUSED_PARAMETER(Stride);
1697 }
1698 
1699 static
1700 cmsUInt8Number* Pack4BytesSwapSwapFirst(register _cmsTRANSFORM* info,
1701                                         register cmsUInt16Number wOut[],
1702                                         register cmsUInt8Number* output,
1703                                         register cmsUInt32Number Stride)
1704 {
1705     *output++ = FROM_16_TO_8(wOut[2]);
1706     *output++ = FROM_16_TO_8(wOut[1]);
1707     *output++ = FROM_16_TO_8(wOut[0]);
1708     *output++ = FROM_16_TO_8(wOut[3]);
1709 
1710     return output;
1711 
1712     cmsUNUSED_PARAMETER(info);
1713     cmsUNUSED_PARAMETER(Stride);
1714 }
1715 
1716 static
1717 cmsUInt8Number* Pack4Words(register _cmsTRANSFORM* info,
1718                            register cmsUInt16Number wOut[],
1719                            register cmsUInt8Number* output,
1720                            register cmsUInt32Number Stride)
1721 {
1722     *(cmsUInt16Number*) output = wOut[0];
1723     output+= 2;
1724     *(cmsUInt16Number*) output = wOut[1];
1725     output+= 2;
1726     *(cmsUInt16Number*) output = wOut[2];
1727     output+= 2;
1728     *(cmsUInt16Number*) output = wOut[3];
1729     output+= 2;
1730 
1731     return output;
1732 
1733     cmsUNUSED_PARAMETER(info);
1734     cmsUNUSED_PARAMETER(Stride);
1735 }
1736 
1737 static
1738 cmsUInt8Number* Pack4WordsReverse(register _cmsTRANSFORM* info,
1739                                   register cmsUInt16Number wOut[],
1740                                   register cmsUInt8Number* output,
1741                                   register cmsUInt32Number Stride)
1742 {
1743     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1744     output+= 2;
1745     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1746     output+= 2;
1747     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1748     output+= 2;
1749     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1750     output+= 2;
1751 
1752     return output;
1753 
1754     cmsUNUSED_PARAMETER(info);
1755     cmsUNUSED_PARAMETER(Stride);
1756 }
1757 
1758 // ABGR
1759 static
1760 cmsUInt8Number* Pack4WordsSwap(register _cmsTRANSFORM* info,
1761                                register cmsUInt16Number wOut[],
1762                                register cmsUInt8Number* output,
1763                                register cmsUInt32Number Stride)
1764 {
1765     *(cmsUInt16Number*) output = wOut[3];
1766     output+= 2;
1767     *(cmsUInt16Number*) output = wOut[2];
1768     output+= 2;
1769     *(cmsUInt16Number*) output = wOut[1];
1770     output+= 2;
1771     *(cmsUInt16Number*) output = wOut[0];
1772     output+= 2;
1773 
1774     return output;
1775 
1776     cmsUNUSED_PARAMETER(info);
1777     cmsUNUSED_PARAMETER(Stride);
1778 }
1779 
1780 // CMYK
1781 static
1782 cmsUInt8Number* Pack4WordsBigEndian(register _cmsTRANSFORM* info,
1783                                     register cmsUInt16Number wOut[],
1784                                     register cmsUInt8Number* output,
1785                                     register cmsUInt32Number Stride)
1786 {
1787     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1788     output+= 2;
1789     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1790     output+= 2;
1791     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1792     output+= 2;
1793     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1794     output+= 2;
1795 
1796     return output;
1797 
1798     cmsUNUSED_PARAMETER(info);
1799     cmsUNUSED_PARAMETER(Stride);
1800 }
1801 
1802 
1803 static
1804 cmsUInt8Number* PackLabV2_8(register _cmsTRANSFORM* info,
1805                             register cmsUInt16Number wOut[],
1806                             register cmsUInt8Number* output,
1807                             register cmsUInt32Number Stride)
1808 {
1809     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1810     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1811     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1812 
1813     return output;
1814 
1815     cmsUNUSED_PARAMETER(info);
1816     cmsUNUSED_PARAMETER(Stride);
1817 }
1818 
1819 static
1820 cmsUInt8Number* PackALabV2_8(register _cmsTRANSFORM* info,
1821                              register cmsUInt16Number wOut[],
1822                              register cmsUInt8Number* output,
1823                              register cmsUInt32Number Stride)
1824 {
1825     output++;
1826     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1827     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1828     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1829 
1830     return output;
1831 
1832     cmsUNUSED_PARAMETER(info);
1833     cmsUNUSED_PARAMETER(Stride);
1834 }
1835 
1836 static
1837 cmsUInt8Number* PackLabV2_16(register _cmsTRANSFORM* info,
1838                              register cmsUInt16Number wOut[],
1839                              register cmsUInt8Number* output,
1840                              register cmsUInt32Number Stride)
1841 {
1842     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1843     output += 2;
1844     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1845     output += 2;
1846     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1847     output += 2;
1848 
1849     return output;
1850 
1851     cmsUNUSED_PARAMETER(info);
1852     cmsUNUSED_PARAMETER(Stride);
1853 }
1854 
1855 static
1856 cmsUInt8Number* Pack3Bytes(register _cmsTRANSFORM* info,
1857                            register cmsUInt16Number wOut[],
1858                            register cmsUInt8Number* output,
1859                            register cmsUInt32Number Stride)
1860 {
1861     *output++ = FROM_16_TO_8(wOut[0]);
1862     *output++ = FROM_16_TO_8(wOut[1]);
1863     *output++ = FROM_16_TO_8(wOut[2]);
1864 
1865     return output;
1866 
1867     cmsUNUSED_PARAMETER(info);
1868     cmsUNUSED_PARAMETER(Stride);
1869 }
1870 
1871 static
1872 cmsUInt8Number* Pack3BytesOptimized(register _cmsTRANSFORM* info,
1873                                     register cmsUInt16Number wOut[],
1874                                     register cmsUInt8Number* output,
1875                                     register cmsUInt32Number Stride)
1876 {
1877     *output++ = (wOut[0] & 0xFFU);
1878     *output++ = (wOut[1] & 0xFFU);
1879     *output++ = (wOut[2] & 0xFFU);
1880 
1881     return output;
1882 
1883     cmsUNUSED_PARAMETER(info);
1884     cmsUNUSED_PARAMETER(Stride);
1885 }
1886 
1887 static
1888 cmsUInt8Number* Pack3BytesSwap(register _cmsTRANSFORM* info,
1889                                register cmsUInt16Number wOut[],
1890                                register cmsUInt8Number* output,
1891                                register cmsUInt32Number Stride)
1892 {
1893     *output++ = FROM_16_TO_8(wOut[2]);
1894     *output++ = FROM_16_TO_8(wOut[1]);
1895     *output++ = FROM_16_TO_8(wOut[0]);
1896 
1897     return output;
1898 
1899     cmsUNUSED_PARAMETER(info);
1900     cmsUNUSED_PARAMETER(Stride);
1901 }
1902 
1903 static
1904 cmsUInt8Number* Pack3BytesSwapOptimized(register _cmsTRANSFORM* info,
1905                                         register cmsUInt16Number wOut[],
1906                                         register cmsUInt8Number* output,
1907                                         register cmsUInt32Number Stride)
1908 {
1909     *output++ = (wOut[2] & 0xFFU);
1910     *output++ = (wOut[1] & 0xFFU);
1911     *output++ = (wOut[0] & 0xFFU);
1912 
1913     return output;
1914 
1915     cmsUNUSED_PARAMETER(info);
1916     cmsUNUSED_PARAMETER(Stride);
1917 }
1918 
1919 
1920 static
1921 cmsUInt8Number* Pack3Words(register _cmsTRANSFORM* info,
1922                            register cmsUInt16Number wOut[],
1923                            register cmsUInt8Number* output,
1924                            register cmsUInt32Number Stride)
1925 {
1926     *(cmsUInt16Number*) output = wOut[0];
1927     output+= 2;
1928     *(cmsUInt16Number*) output = wOut[1];
1929     output+= 2;
1930     *(cmsUInt16Number*) output = wOut[2];
1931     output+= 2;
1932 
1933     return output;
1934 
1935     cmsUNUSED_PARAMETER(info);
1936     cmsUNUSED_PARAMETER(Stride);
1937 }
1938 
1939 static
1940 cmsUInt8Number* Pack3WordsSwap(register _cmsTRANSFORM* info,
1941                                register cmsUInt16Number wOut[],
1942                                register cmsUInt8Number* output,
1943                                register cmsUInt32Number Stride)
1944 {
1945     *(cmsUInt16Number*) output = wOut[2];
1946     output+= 2;
1947     *(cmsUInt16Number*) output = wOut[1];
1948     output+= 2;
1949     *(cmsUInt16Number*) output = wOut[0];
1950     output+= 2;
1951 
1952     return output;
1953 
1954     cmsUNUSED_PARAMETER(info);
1955     cmsUNUSED_PARAMETER(Stride);
1956 }
1957 
1958 static
1959 cmsUInt8Number* Pack3WordsBigEndian(register _cmsTRANSFORM* info,
1960                                     register cmsUInt16Number wOut[],
1961                                     register cmsUInt8Number* output,
1962                                     register cmsUInt32Number Stride)
1963 {
1964     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1965     output+= 2;
1966     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1967     output+= 2;
1968     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1969     output+= 2;
1970 
1971     return output;
1972 
1973     cmsUNUSED_PARAMETER(info);
1974     cmsUNUSED_PARAMETER(Stride);
1975 }
1976 
1977 static
1978 cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
1979                                    register cmsUInt16Number wOut[],
1980                                    register cmsUInt8Number* output,
1981                                    register cmsUInt32Number Stride)
1982 {
1983     *output++ = FROM_16_TO_8(wOut[0]);
1984     *output++ = FROM_16_TO_8(wOut[1]);
1985     *output++ = FROM_16_TO_8(wOut[2]);
1986     output++;
1987 
1988     return output;
1989 
1990     cmsUNUSED_PARAMETER(info);
1991     cmsUNUSED_PARAMETER(Stride);
1992 }
1993 
1994 static
1995 cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
1996                                             register cmsUInt16Number wOut[],
1997                                             register cmsUInt8Number* output,
1998                                             register cmsUInt32Number Stride)
1999 {
2000     *output++ = (wOut[0] & 0xFFU);
2001     *output++ = (wOut[1] & 0xFFU);
2002     *output++ = (wOut[2] & 0xFFU);
2003     output++;
2004 
2005     return output;
2006 
2007     cmsUNUSED_PARAMETER(info);
2008     cmsUNUSED_PARAMETER(Stride);
2009 }
2010 
2011 
2012 static
2013 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2014                                             register cmsUInt16Number wOut[],
2015                                             register cmsUInt8Number* output,
2016                                             register cmsUInt32Number Stride)
2017 {
2018     output++;
2019     *output++ = FROM_16_TO_8(wOut[0]);
2020     *output++ = FROM_16_TO_8(wOut[1]);
2021     *output++ = FROM_16_TO_8(wOut[2]);
2022 
2023     return output;
2024 
2025     cmsUNUSED_PARAMETER(info);
2026     cmsUNUSED_PARAMETER(Stride);
2027 }
2028 
2029 static
2030 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
2031                                                      register cmsUInt16Number wOut[],
2032                                                      register cmsUInt8Number* output,
2033                                                      register cmsUInt32Number Stride)
2034 {
2035     output++;
2036     *output++ = (wOut[0] & 0xFFU);
2037     *output++ = (wOut[1] & 0xFFU);
2038     *output++ = (wOut[2] & 0xFFU);
2039 
2040     return output;
2041 
2042     cmsUNUSED_PARAMETER(info);
2043     cmsUNUSED_PARAMETER(Stride);
2044 }
2045 
2046 static
2047 cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
2048                                        register cmsUInt16Number wOut[],
2049                                        register cmsUInt8Number* output,
2050                                        register cmsUInt32Number Stride)
2051 {
2052     output++;
2053     *output++ = FROM_16_TO_8(wOut[2]);
2054     *output++ = FROM_16_TO_8(wOut[1]);
2055     *output++ = FROM_16_TO_8(wOut[0]);
2056 
2057     return output;
2058 
2059     cmsUNUSED_PARAMETER(info);
2060     cmsUNUSED_PARAMETER(Stride);
2061 }
2062 
2063 static
2064 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
2065                                                 register cmsUInt16Number wOut[],
2066                                                 register cmsUInt8Number* output,
2067                                                 register cmsUInt32Number Stride)
2068 {
2069     output++;
2070     *output++ = (wOut[2] & 0xFFU);
2071     *output++ = (wOut[1] & 0xFFU);
2072     *output++ = (wOut[0] & 0xFFU);
2073 
2074     return output;
2075 
2076     cmsUNUSED_PARAMETER(info);
2077     cmsUNUSED_PARAMETER(Stride);
2078 }
2079 
2080 
2081 static
2082 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2083                                                 register cmsUInt16Number wOut[],
2084                                                 register cmsUInt8Number* output,
2085                                                 register cmsUInt32Number Stride)
2086 {
2087     *output++ = FROM_16_TO_8(wOut[2]);
2088     *output++ = FROM_16_TO_8(wOut[1]);
2089     *output++ = FROM_16_TO_8(wOut[0]);
2090     output++;
2091 
2092     return output;
2093 
2094     cmsUNUSED_PARAMETER(info);
2095     cmsUNUSED_PARAMETER(Stride);
2096 }
2097 
2098 static
2099 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
2100                                                          register cmsUInt16Number wOut[],
2101                                                          register cmsUInt8Number* output,
2102                                                          register cmsUInt32Number Stride)
2103 {
2104     *output++ = (wOut[2] & 0xFFU);
2105     *output++ = (wOut[1] & 0xFFU);
2106     *output++ = (wOut[0] & 0xFFU);
2107     output++;
2108 
2109     return output;
2110 
2111     cmsUNUSED_PARAMETER(info);
2112     cmsUNUSED_PARAMETER(Stride);
2113 }
2114 
2115 static
2116 cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
2117                                    register cmsUInt16Number wOut[],
2118                                    register cmsUInt8Number* output,
2119                                    register cmsUInt32Number Stride)
2120 {
2121     *(cmsUInt16Number*) output = wOut[0];
2122     output+= 2;
2123     *(cmsUInt16Number*) output = wOut[1];
2124     output+= 2;
2125     *(cmsUInt16Number*) output = wOut[2];
2126     output+= 2;
2127     output+= 2;
2128 
2129     return output;
2130 
2131     cmsUNUSED_PARAMETER(info);
2132     cmsUNUSED_PARAMETER(Stride);
2133 }
2134 
2135 static
2136 cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
2137                                        register cmsUInt16Number wOut[],
2138                                        register cmsUInt8Number* output,
2139                                        register cmsUInt32Number Stride)
2140 {
2141     output+= 2;
2142     *(cmsUInt16Number*) output = wOut[2];
2143     output+= 2;
2144     *(cmsUInt16Number*) output = wOut[1];
2145     output+= 2;
2146     *(cmsUInt16Number*) output = wOut[0];
2147     output+= 2;
2148 
2149     return output;
2150 
2151     cmsUNUSED_PARAMETER(info);
2152     cmsUNUSED_PARAMETER(Stride);
2153 }
2154 
2155 
2156 static
2157 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
2158                                             register cmsUInt16Number wOut[],
2159                                             register cmsUInt8Number* output,
2160                                             register cmsUInt32Number Stride)
2161 {
2162     output+= 2;
2163     *(cmsUInt16Number*) output = wOut[0];
2164     output+= 2;
2165     *(cmsUInt16Number*) output = wOut[1];
2166     output+= 2;
2167     *(cmsUInt16Number*) output = wOut[2];
2168     output+= 2;
2169 
2170     return output;
2171 
2172     cmsUNUSED_PARAMETER(info);
2173     cmsUNUSED_PARAMETER(Stride);
2174 }
2175 
2176 
2177 static
2178 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
2179                                                 register cmsUInt16Number wOut[],
2180                                                 register cmsUInt8Number* output,
2181                                                 register cmsUInt32Number Stride)
2182 {
2183     *(cmsUInt16Number*) output = wOut[2];
2184     output+= 2;
2185     *(cmsUInt16Number*) output = wOut[1];
2186     output+= 2;
2187     *(cmsUInt16Number*) output = wOut[0];
2188     output+= 2;
2189     output+= 2;
2190 
2191     return output;
2192 
2193     cmsUNUSED_PARAMETER(info);
2194     cmsUNUSED_PARAMETER(Stride);
2195 }
2196 
2197 
2198 
2199 static
2200 cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
2201                           register cmsUInt16Number wOut[],
2202                           register cmsUInt8Number* output,
2203                           register cmsUInt32Number Stride)
2204 {
2205     *output++ = FROM_16_TO_8(wOut[0]);
2206 
2207     return output;
2208 
2209     cmsUNUSED_PARAMETER(info);
2210     cmsUNUSED_PARAMETER(Stride);
2211 }
2212 
2213 
2214 static
2215 cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
2216                                   register cmsUInt16Number wOut[],
2217                                   register cmsUInt8Number* output,
2218                                   register cmsUInt32Number Stride)
2219 {
2220     *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2221 
2222     return output;
2223 
2224     cmsUNUSED_PARAMETER(info);
2225     cmsUNUSED_PARAMETER(Stride);
2226 }
2227 
2228 
2229 static
2230 cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
2231                                register cmsUInt16Number wOut[],
2232                                register cmsUInt8Number* output,
2233                                register cmsUInt32Number Stride)
2234 {
2235     *output++ = FROM_16_TO_8(wOut[0]);
2236     output++;
2237 
2238     return output;
2239 
2240     cmsUNUSED_PARAMETER(info);
2241     cmsUNUSED_PARAMETER(Stride);
2242 }
2243 
2244 
2245 static
2246 cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
2247                                         register cmsUInt16Number wOut[],
2248                                         register cmsUInt8Number* output,
2249                                         register cmsUInt32Number Stride)
2250 {
2251     output++;
2252     *output++ = FROM_16_TO_8(wOut[0]);
2253 
2254     return output;
2255 
2256     cmsUNUSED_PARAMETER(info);
2257     cmsUNUSED_PARAMETER(Stride);
2258 }
2259 
2260 static
2261 cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
2262                           register cmsUInt16Number wOut[],
2263                           register cmsUInt8Number* output,
2264                           register cmsUInt32Number Stride)
2265 {
2266     *(cmsUInt16Number*) output = wOut[0];
2267     output+= 2;
2268 
2269     return output;
2270 
2271     cmsUNUSED_PARAMETER(info);
2272     cmsUNUSED_PARAMETER(Stride);
2273 }
2274 
2275 
2276 static
2277 cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
2278                                   register cmsUInt16Number wOut[],
2279                                   register cmsUInt8Number* output,
2280                                   register cmsUInt32Number Stride)
2281 {
2282     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2283     output+= 2;
2284 
2285     return output;
2286 
2287     cmsUNUSED_PARAMETER(info);
2288     cmsUNUSED_PARAMETER(Stride);
2289 }
2290 
2291 static
2292 cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
2293                                    register cmsUInt16Number wOut[],
2294                                    register cmsUInt8Number* output,
2295                                    register cmsUInt32Number Stride)
2296 {
2297     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2298     output+= 2;
2299 
2300     return output;
2301 
2302     cmsUNUSED_PARAMETER(info);
2303     cmsUNUSED_PARAMETER(Stride);
2304 }
2305 
2306 
2307 static
2308 cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
2309                                register cmsUInt16Number wOut[],
2310                                register cmsUInt8Number* output,
2311                                register cmsUInt32Number Stride)
2312 {
2313     *(cmsUInt16Number*) output = wOut[0];
2314     output+= 4;
2315 
2316     return output;
2317 
2318     cmsUNUSED_PARAMETER(info);
2319     cmsUNUSED_PARAMETER(Stride);
2320 }
2321 
2322 static
2323 cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
2324                                         register cmsUInt16Number wOut[],
2325                                         register cmsUInt8Number* output,
2326                                         register cmsUInt32Number Stride)
2327 {
2328     output += 2;
2329     *(cmsUInt16Number*) output = wOut[0];
2330     output+= 2;
2331 
2332     return output;
2333 
2334     cmsUNUSED_PARAMETER(info);
2335     cmsUNUSED_PARAMETER(Stride);
2336 }
2337 
2338 
2339 // Unencoded Float values -- don't try optimize speed
2340 static
2341 cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
2342                                     register cmsUInt16Number wOut[],
2343                                     register cmsUInt8Number* output,
2344                                     register cmsUInt32Number Stride)
2345 {
2346 
2347     if (T_PLANAR(info -> OutputFormat)) {
2348 
2349         cmsCIELab  Lab;
2350         cmsFloat64Number* Out = (cmsFloat64Number*) output;
2351         cmsLabEncoded2Float(&Lab, wOut);
2352 
2353         Out[0]        = Lab.L;
2354         Out[Stride]   = Lab.a;
2355         Out[Stride*2] = Lab.b;
2356 
2357         return output + sizeof(cmsFloat64Number);
2358     }
2359     else {
2360 
2361         cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2362         return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2363     }
2364 }
2365 
2366 
2367 static
2368 cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
2369                                     register cmsUInt16Number wOut[],
2370                                     register cmsUInt8Number* output,
2371                                     register cmsUInt32Number Stride)
2372 {
2373     cmsCIELab  Lab;
2374     cmsLabEncoded2Float(&Lab, wOut);
2375 
2376     if (T_PLANAR(info -> OutputFormat)) {
2377 
2378         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2379 
2380         Stride /= PixelSize(info->OutputFormat);
2381 
2382         Out[0]        = (cmsFloat32Number)Lab.L;
2383         Out[Stride]   = (cmsFloat32Number)Lab.a;
2384         Out[Stride*2] = (cmsFloat32Number)Lab.b;
2385 
2386         return output + sizeof(cmsFloat32Number);
2387     }
2388     else {
2389 
2390        ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2391        ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2392        ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2393 
2394         return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2395     }
2396 }
2397 
2398 static
2399 cmsUInt8Number* PackXYZDoubleFrom16(register _cmsTRANSFORM* Info,
2400                                     register cmsUInt16Number wOut[],
2401                                     register cmsUInt8Number* output,
2402                                     register cmsUInt32Number Stride)
2403 {
2404     if (T_PLANAR(Info -> OutputFormat)) {
2405 
2406         cmsCIEXYZ XYZ;
2407         cmsFloat64Number* Out = (cmsFloat64Number*) output;
2408         cmsXYZEncoded2Float(&XYZ, wOut);
2409 
2410         Stride /= PixelSize(Info->OutputFormat);
2411 
2412         Out[0]        = XYZ.X;
2413         Out[Stride]   = XYZ.Y;
2414         Out[Stride*2] = XYZ.Z;
2415 
2416         return output + sizeof(cmsFloat64Number);
2417 
2418     }
2419     else {
2420 
2421         cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2422 
2423         return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2424     }
2425 }
2426 
2427 static
2428 cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
2429                                    register cmsUInt16Number wOut[],
2430                                    register cmsUInt8Number* output,
2431                                    register cmsUInt32Number Stride)
2432 {
2433     if (T_PLANAR(Info -> OutputFormat)) {
2434 
2435         cmsCIEXYZ XYZ;
2436         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2437         cmsXYZEncoded2Float(&XYZ, wOut);
2438 
2439         Stride /= PixelSize(Info->OutputFormat);
2440 
2441         Out[0]        = (cmsFloat32Number) XYZ.X;
2442         Out[Stride]   = (cmsFloat32Number) XYZ.Y;
2443         Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
2444 
2445         return output + sizeof(cmsFloat32Number);
2446 
2447     }
2448     else {
2449 
2450         cmsCIEXYZ XYZ;
2451         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2452         cmsXYZEncoded2Float(&XYZ, wOut);
2453 
2454         Out[0] = (cmsFloat32Number) XYZ.X;
2455         Out[1] = (cmsFloat32Number) XYZ.Y;
2456         Out[2] = (cmsFloat32Number) XYZ.Z;
2457 
2458         return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2459     }
2460 }
2461 
2462 static
2463 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
2464                                 register cmsUInt16Number wOut[],
2465                                 register cmsUInt8Number* output,
2466                                 register cmsUInt32Number Stride)
2467 {
2468     cmsUInt32Number nChan      = T_CHANNELS(info -> OutputFormat);
2469     cmsUInt32Number DoSwap     = T_DOSWAP(info ->OutputFormat);
2470     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
2471     cmsUInt32Number Extra      = T_EXTRA(info -> OutputFormat);
2472     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
2473     cmsUInt32Number Planar     = T_PLANAR(info -> OutputFormat);
2474     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2475     cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2476     cmsFloat64Number v = 0;
2477     cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2478     cmsUInt32Number i, start = 0;
2479 
2480     Stride /= PixelSize(info->OutputFormat);
2481 
2482     if (ExtraFirst)
2483         start = Extra;
2484 
2485     for (i=0; i < nChan; i++) {
2486 


2496         else
2497             ((cmsFloat64Number*) output)[i + start] = v;
2498     }
2499 
2500 
2501     if (Extra == 0 && SwapFirst) {
2502 
2503          memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2504         *swap1 = v;
2505     }
2506 
2507     if (T_PLANAR(info -> OutputFormat))
2508         return output + sizeof(cmsFloat64Number);
2509     else
2510         return output + (nChan + Extra) * sizeof(cmsFloat64Number);
2511 
2512 }
2513 
2514 
2515 static
2516 cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
2517                                 register cmsUInt16Number wOut[],
2518                                 register cmsUInt8Number* output,
2519                                 register cmsUInt32Number Stride)
2520 {
2521        cmsUInt32Number nChan      = T_CHANNELS(info->OutputFormat);
2522        cmsUInt32Number DoSwap     = T_DOSWAP(info->OutputFormat);
2523        cmsUInt32Number Reverse    = T_FLAVOR(info->OutputFormat);
2524        cmsUInt32Number Extra      = T_EXTRA(info->OutputFormat);
2525        cmsUInt32Number SwapFirst  = T_SWAPFIRST(info->OutputFormat);
2526        cmsUInt32Number Planar     = T_PLANAR(info->OutputFormat);
2527        cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2528        cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
2529        cmsFloat64Number v = 0;
2530        cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2531        cmsUInt32Number i, start = 0;
2532 
2533        Stride /= PixelSize(info->OutputFormat);
2534 
2535        if (ExtraFirst)
2536               start = Extra;
2537 
2538        for (i = 0; i < nChan; i++) {
2539 


2785     }
2786     else {
2787 
2788         Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2789         Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2790         Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2791 
2792         return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2793     }
2794 
2795 }
2796 
2797 
2798 // ----------------------------------------------------------------------------------------------------------------
2799 
2800 #ifndef CMS_NO_HALF_SUPPORT
2801 
2802 // Decodes an stream of half floats to wIn[] described by input format
2803 
2804 static
2805 cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
2806                                 register cmsUInt16Number wIn[],
2807                                 register cmsUInt8Number* accum,
2808                                 register cmsUInt32Number Stride)
2809 {
2810 
2811     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
2812     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
2813     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
2814     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
2815     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
2816     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2817     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
2818     cmsFloat32Number v;
2819     cmsUInt32Number i, start = 0;
2820     cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2821 
2822 
2823     Stride /= PixelSize(info->OutputFormat);
2824 
2825     if (ExtraFirst)
2826             start = Extra;
2827 
2828     for (i=0; i < nChan; i++) {


2891 
2892         wIn[index] = Reverse ? 1 - v : v;
2893     }
2894 
2895 
2896     if (Extra == 0 && SwapFirst) {
2897         cmsFloat32Number tmp = wIn[0];
2898 
2899         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2900         wIn[nChan-1] = tmp;
2901     }
2902 
2903     if (T_PLANAR(info -> InputFormat))
2904         return accum + sizeof(cmsUInt16Number);
2905     else
2906         return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2907 }
2908 
2909 
2910 static
2911 cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
2912                                 register cmsUInt16Number wOut[],
2913                                 register cmsUInt8Number* output,
2914                                 register cmsUInt32Number Stride)
2915 {
2916        cmsUInt32Number nChan      = T_CHANNELS(info->OutputFormat);
2917        cmsUInt32Number DoSwap     = T_DOSWAP(info->OutputFormat);
2918        cmsUInt32Number Reverse    = T_FLAVOR(info->OutputFormat);
2919        cmsUInt32Number Extra      = T_EXTRA(info->OutputFormat);
2920        cmsUInt32Number SwapFirst  = T_SWAPFIRST(info->OutputFormat);
2921        cmsUInt32Number Planar     = T_PLANAR(info->OutputFormat);
2922        cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2923        cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
2924        cmsFloat32Number v = 0;
2925        cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
2926        cmsUInt32Number i, start = 0;
2927 
2928        Stride /= PixelSize(info->OutputFormat);
2929 
2930        if (ExtraFirst)
2931               start = Extra;
2932 
2933        for (i = 0; i < nChan; i++) {
2934 




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2020 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 104 #define ANYCHANNELS     CHANNELS_SH(15)
 105 #define ANYEXTRA        EXTRA_SH(7)
 106 #define ANYPLANAR       PLANAR_SH(1)
 107 #define ANYENDIAN       ENDIAN16_SH(1)
 108 #define ANYSWAP         DOSWAP_SH(1)
 109 #define ANYSWAPFIRST    SWAPFIRST_SH(1)
 110 #define ANYFLAVOR       FLAVOR_SH(1)
 111 
 112 
 113 // Suppress waning about info never being used
 114 
 115 #ifdef _MSC_VER
 116 #pragma warning(disable : 4100)
 117 #endif
 118 
 119 // Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
 120 
 121 
 122 // Does almost everything but is slow
 123 static
 124 cmsUInt8Number* UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM* info,
 125                                   CMSREGISTER cmsUInt16Number wIn[],
 126                                   CMSREGISTER cmsUInt8Number* accum,
 127                                   CMSREGISTER cmsUInt32Number Stride)
 128 {
 129     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
 130     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
 131     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
 132     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
 133     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
 134     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
 135     cmsUInt16Number v;
 136     cmsUInt32Number i;
 137 
 138     if (ExtraFirst) {
 139         accum += Extra;
 140     }
 141 
 142     for (i=0; i < nChan; i++) {
 143         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 144 
 145         v = FROM_8_TO_16(*accum);
 146         v = Reverse ? REVERSE_FLAVOR_16(v) : v;
 147         wIn[index] = v;


 151     if (!ExtraFirst) {
 152         accum += Extra;
 153     }
 154 
 155     if (Extra == 0 && SwapFirst) {
 156         cmsUInt16Number tmp = wIn[0];
 157 
 158         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
 159         wIn[nChan-1] = tmp;
 160     }
 161 
 162     return accum;
 163 
 164     cmsUNUSED_PARAMETER(info);
 165     cmsUNUSED_PARAMETER(Stride);
 166 
 167 }
 168 
 169 // Extra channels are just ignored because come in the next planes
 170 static
 171 cmsUInt8Number* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
 172                                   CMSREGISTER cmsUInt16Number wIn[],
 173                                   CMSREGISTER cmsUInt8Number* accum,
 174                                   CMSREGISTER cmsUInt32Number Stride)
 175 {
 176     cmsUInt32Number nChan     = T_CHANNELS(info -> InputFormat);
 177     cmsUInt32Number DoSwap    = T_DOSWAP(info ->InputFormat);
 178     cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat);
 179     cmsUInt32Number Reverse   = T_FLAVOR(info ->InputFormat);
 180     cmsUInt32Number i;
 181     cmsUInt8Number* Init = accum;
 182 
 183     if (DoSwap ^ SwapFirst) {
 184         accum += T_EXTRA(info -> InputFormat) * Stride;
 185     }
 186 
 187     for (i=0; i < nChan; i++) {
 188 
 189         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 190         cmsUInt16Number v = FROM_8_TO_16(*accum);
 191 
 192         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 193         accum += Stride;
 194     }
 195 
 196     return (Init + 1);
 197 }
 198 
 199 // Special cases, provided for performance
 200 static
 201 cmsUInt8Number* Unroll4Bytes(CMSREGISTER _cmsTRANSFORM* info,
 202                              CMSREGISTER cmsUInt16Number wIn[],
 203                              CMSREGISTER cmsUInt8Number* accum,
 204                              CMSREGISTER cmsUInt32Number Stride)
 205 {
 206     wIn[0] = FROM_8_TO_16(*accum); accum++; // C
 207     wIn[1] = FROM_8_TO_16(*accum); accum++; // M
 208     wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
 209     wIn[3] = FROM_8_TO_16(*accum); accum++; // K
 210 
 211     return accum;
 212 
 213     cmsUNUSED_PARAMETER(info);
 214     cmsUNUSED_PARAMETER(Stride);
 215 }
 216 
 217 static
 218 cmsUInt8Number* Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
 219                                     CMSREGISTER cmsUInt16Number wIn[],
 220                                     CMSREGISTER cmsUInt8Number* accum,
 221                                     CMSREGISTER cmsUInt32Number Stride)
 222 {
 223     wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
 224     wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
 225     wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
 226     wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
 227 
 228     return accum;
 229 
 230     cmsUNUSED_PARAMETER(info);
 231     cmsUNUSED_PARAMETER(Stride);
 232 }
 233 
 234 static
 235 cmsUInt8Number* Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 236                                       CMSREGISTER cmsUInt16Number wIn[],
 237                                       CMSREGISTER cmsUInt8Number* accum,
 238                                       CMSREGISTER cmsUInt32Number Stride)
 239 {
 240     wIn[3] = FROM_8_TO_16(*accum); accum++; // K
 241     wIn[0] = FROM_8_TO_16(*accum); accum++; // C
 242     wIn[1] = FROM_8_TO_16(*accum); accum++; // M
 243     wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
 244 
 245     return accum;
 246 
 247     cmsUNUSED_PARAMETER(info);
 248     cmsUNUSED_PARAMETER(Stride);
 249 }
 250 
 251 // KYMC
 252 static
 253 cmsUInt8Number* Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
 254                                  CMSREGISTER cmsUInt16Number wIn[],
 255                                  CMSREGISTER cmsUInt8Number* accum,
 256                                  CMSREGISTER cmsUInt32Number Stride)
 257 {
 258     wIn[3] = FROM_8_TO_16(*accum); accum++;  // K
 259     wIn[2] = FROM_8_TO_16(*accum); accum++;  // Y
 260     wIn[1] = FROM_8_TO_16(*accum); accum++;  // M
 261     wIn[0] = FROM_8_TO_16(*accum); accum++;  // C
 262 
 263     return accum;
 264 
 265     cmsUNUSED_PARAMETER(info);
 266     cmsUNUSED_PARAMETER(Stride);
 267 }
 268 
 269 static
 270 cmsUInt8Number* Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 271                                           CMSREGISTER cmsUInt16Number wIn[],
 272                                           CMSREGISTER cmsUInt8Number* accum,
 273                                           CMSREGISTER cmsUInt32Number Stride)
 274 {
 275     wIn[2] = FROM_8_TO_16(*accum); accum++;  // K
 276     wIn[1] = FROM_8_TO_16(*accum); accum++;  // Y
 277     wIn[0] = FROM_8_TO_16(*accum); accum++;  // M
 278     wIn[3] = FROM_8_TO_16(*accum); accum++;  // C
 279 
 280     return accum;
 281 
 282     cmsUNUSED_PARAMETER(info);
 283     cmsUNUSED_PARAMETER(Stride);
 284 }
 285 
 286 static
 287 cmsUInt8Number* Unroll3Bytes(CMSREGISTER _cmsTRANSFORM* info,
 288                              CMSREGISTER cmsUInt16Number wIn[],
 289                              CMSREGISTER cmsUInt8Number* accum,
 290                              CMSREGISTER cmsUInt32Number Stride)
 291 {
 292     wIn[0] = FROM_8_TO_16(*accum); accum++;     // R
 293     wIn[1] = FROM_8_TO_16(*accum); accum++;     // G
 294     wIn[2] = FROM_8_TO_16(*accum); accum++;     // B
 295 
 296     return accum;
 297 
 298     cmsUNUSED_PARAMETER(info);
 299     cmsUNUSED_PARAMETER(Stride);
 300 }
 301 
 302 static
 303 cmsUInt8Number* Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
 304                                       CMSREGISTER cmsUInt16Number wIn[],
 305                                       CMSREGISTER cmsUInt8Number* accum,
 306                                       CMSREGISTER cmsUInt32Number Stride)
 307 {
 308     accum++; // A
 309     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 310     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 311     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 312 
 313     return accum;
 314 
 315     cmsUNUSED_PARAMETER(info);
 316     cmsUNUSED_PARAMETER(Stride);
 317 }
 318 
 319 static
 320 cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 321                                               CMSREGISTER cmsUInt16Number wIn[],
 322                                               CMSREGISTER cmsUInt8Number* accum,
 323                                               CMSREGISTER cmsUInt32Number Stride)
 324 {
 325     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 326     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 327     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 328     accum++; // A
 329 
 330     return accum;
 331 
 332     cmsUNUSED_PARAMETER(info);
 333     cmsUNUSED_PARAMETER(Stride);
 334 }
 335 
 336 static
 337 cmsUInt8Number* Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 338                                            CMSREGISTER cmsUInt16Number wIn[],
 339                                            CMSREGISTER cmsUInt8Number* accum,
 340                                            CMSREGISTER cmsUInt32Number Stride)
 341 {
 342     accum++; // A
 343     wIn[0] = FROM_8_TO_16(*accum); accum++; // R
 344     wIn[1] = FROM_8_TO_16(*accum); accum++; // G
 345     wIn[2] = FROM_8_TO_16(*accum); accum++; // B
 346 
 347     return accum;
 348 
 349     cmsUNUSED_PARAMETER(info);
 350     cmsUNUSED_PARAMETER(Stride);
 351 }
 352 
 353 
 354 // BRG
 355 static
 356 cmsUInt8Number* Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
 357                                  CMSREGISTER cmsUInt16Number wIn[],
 358                                  CMSREGISTER cmsUInt8Number* accum,
 359                                  CMSREGISTER cmsUInt32Number Stride)
 360 {
 361     wIn[2] = FROM_8_TO_16(*accum); accum++;     // B
 362     wIn[1] = FROM_8_TO_16(*accum); accum++;     // G
 363     wIn[0] = FROM_8_TO_16(*accum); accum++;     // R
 364 
 365     return accum;
 366 
 367     cmsUNUSED_PARAMETER(info);
 368     cmsUNUSED_PARAMETER(Stride);
 369 }
 370 
 371 static
 372 cmsUInt8Number* UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
 373                               CMSREGISTER cmsUInt16Number wIn[],
 374                               CMSREGISTER cmsUInt8Number* accum,
 375                               CMSREGISTER cmsUInt32Number Stride)
 376 {
 377     wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // L
 378     wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // a
 379     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 380 
 381     return accum;
 382 
 383     cmsUNUSED_PARAMETER(info);
 384     cmsUNUSED_PARAMETER(Stride);
 385 }
 386 
 387 static
 388 cmsUInt8Number* UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
 389                                CMSREGISTER cmsUInt16Number wIn[],
 390                                CMSREGISTER cmsUInt8Number* accum,
 391                                CMSREGISTER cmsUInt32Number Stride)
 392 {
 393     accum++;  // A
 394     wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // L
 395     wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // a
 396     wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++;     // b
 397 
 398     return accum;
 399 
 400     cmsUNUSED_PARAMETER(info);
 401     cmsUNUSED_PARAMETER(Stride);
 402 }
 403 
 404 static
 405 cmsUInt8Number* UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
 406                                CMSREGISTER cmsUInt16Number wIn[],
 407                                CMSREGISTER cmsUInt8Number* accum,
 408                                CMSREGISTER cmsUInt32Number Stride)
 409 {
 410     wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // L
 411     wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // a
 412     wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2;     // b
 413 
 414     return accum;
 415 
 416     cmsUNUSED_PARAMETER(info);
 417     cmsUNUSED_PARAMETER(Stride);
 418 }
 419 
 420 // for duplex
 421 static
 422 cmsUInt8Number* Unroll2Bytes(CMSREGISTER _cmsTRANSFORM* info,
 423                                      CMSREGISTER cmsUInt16Number wIn[],
 424                                      CMSREGISTER cmsUInt8Number* accum,
 425                                      CMSREGISTER cmsUInt32Number Stride)
 426 {
 427     wIn[0] = FROM_8_TO_16(*accum); accum++;     // ch1
 428     wIn[1] = FROM_8_TO_16(*accum); accum++;     // ch2
 429 
 430     return accum;
 431 
 432     cmsUNUSED_PARAMETER(info);
 433     cmsUNUSED_PARAMETER(Stride);
 434 }
 435 
 436 
 437 
 438 
 439 // Monochrome duplicates L into RGB for null-transforms
 440 static
 441 cmsUInt8Number* Unroll1Byte(CMSREGISTER _cmsTRANSFORM* info,
 442                             CMSREGISTER cmsUInt16Number wIn[],
 443                             CMSREGISTER cmsUInt8Number* accum,
 444                             CMSREGISTER cmsUInt32Number Stride)
 445 {
 446     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 447 
 448     return accum;
 449 
 450     cmsUNUSED_PARAMETER(info);
 451     cmsUNUSED_PARAMETER(Stride);
 452 }
 453 
 454 
 455 static
 456 cmsUInt8Number* Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
 457                                  CMSREGISTER cmsUInt16Number wIn[],
 458                                  CMSREGISTER cmsUInt8Number* accum,
 459                                  CMSREGISTER cmsUInt32Number Stride)
 460 {
 461     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 462     accum += 1;
 463 
 464     return accum;
 465 
 466     cmsUNUSED_PARAMETER(info);
 467     cmsUNUSED_PARAMETER(Stride);
 468 }
 469 
 470 static
 471 cmsUInt8Number* Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM* info,
 472                                  CMSREGISTER cmsUInt16Number wIn[],
 473                                  CMSREGISTER cmsUInt8Number* accum,
 474                                  CMSREGISTER cmsUInt32Number Stride)
 475 {
 476     wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++;     // L
 477     accum += 2;
 478 
 479     return accum;
 480 
 481     cmsUNUSED_PARAMETER(info);
 482     cmsUNUSED_PARAMETER(Stride);
 483 }
 484 
 485 static
 486 cmsUInt8Number* Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
 487                                     CMSREGISTER cmsUInt16Number wIn[],
 488                                     CMSREGISTER cmsUInt8Number* accum,
 489                                     CMSREGISTER cmsUInt32Number Stride)
 490 {
 491     wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++;     // L
 492 
 493     return accum;
 494 
 495     cmsUNUSED_PARAMETER(info);
 496     cmsUNUSED_PARAMETER(Stride);
 497 }
 498 
 499 
 500 static
 501 cmsUInt8Number* UnrollAnyWords(CMSREGISTER _cmsTRANSFORM* info,
 502                                CMSREGISTER cmsUInt16Number wIn[],
 503                                CMSREGISTER cmsUInt8Number* accum,
 504                                CMSREGISTER cmsUInt32Number Stride)
 505 {
 506    cmsUInt32Number nChan       = T_CHANNELS(info -> InputFormat);
 507    cmsUInt32Number SwapEndian  = T_ENDIAN16(info -> InputFormat);
 508    cmsUInt32Number DoSwap      = T_DOSWAP(info ->InputFormat);
 509    cmsUInt32Number Reverse     = T_FLAVOR(info ->InputFormat);
 510    cmsUInt32Number SwapFirst   = T_SWAPFIRST(info -> InputFormat);
 511    cmsUInt32Number Extra       = T_EXTRA(info -> InputFormat);
 512    cmsUInt32Number ExtraFirst  = DoSwap ^ SwapFirst;
 513    cmsUInt32Number i;
 514 
 515     if (ExtraFirst) {
 516         accum += Extra * sizeof(cmsUInt16Number);
 517     }
 518 
 519     for (i=0; i < nChan; i++) {
 520 
 521         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 522         cmsUInt16Number v = *(cmsUInt16Number*) accum;
 523 
 524         if (SwapEndian)


 530     }
 531 
 532     if (!ExtraFirst) {
 533         accum += Extra * sizeof(cmsUInt16Number);
 534     }
 535 
 536     if (Extra == 0 && SwapFirst) {
 537 
 538         cmsUInt16Number tmp = wIn[0];
 539 
 540         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
 541         wIn[nChan-1] = tmp;
 542     }
 543 
 544     return accum;
 545 
 546     cmsUNUSED_PARAMETER(Stride);
 547 }
 548 
 549 static
 550 cmsUInt8Number* UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
 551                                   CMSREGISTER cmsUInt16Number wIn[],
 552                                   CMSREGISTER cmsUInt8Number* accum,
 553                                   CMSREGISTER cmsUInt32Number Stride)
 554 {
 555     cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
 556     cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
 557     cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
 558     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
 559     cmsUInt32Number i;
 560     cmsUInt8Number* Init = accum;
 561 
 562     if (DoSwap) {
 563         accum += T_EXTRA(info -> InputFormat) * Stride;
 564     }
 565 
 566     for (i=0; i < nChan; i++) {
 567 
 568         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
 569         cmsUInt16Number v = *(cmsUInt16Number*) accum;
 570 
 571         if (SwapEndian)
 572             v = CHANGE_ENDIAN(v);
 573 
 574         wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
 575 
 576         accum +=  Stride;
 577     }
 578 
 579     return (Init + sizeof(cmsUInt16Number));
 580 }
 581 
 582 
 583 static
 584 cmsUInt8Number* Unroll4Words(CMSREGISTER _cmsTRANSFORM* info,
 585                              CMSREGISTER cmsUInt16Number wIn[],
 586                              CMSREGISTER cmsUInt8Number* accum,
 587                              CMSREGISTER cmsUInt32Number Stride)
 588 {
 589     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 590     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 591     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 592     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 593 
 594     return accum;
 595 
 596     cmsUNUSED_PARAMETER(info);
 597     cmsUNUSED_PARAMETER(Stride);
 598 }
 599 
 600 static
 601 cmsUInt8Number* Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
 602                                     CMSREGISTER cmsUInt16Number wIn[],
 603                                     CMSREGISTER cmsUInt8Number* accum,
 604                                     CMSREGISTER cmsUInt32Number Stride)
 605 {
 606     wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
 607     wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
 608     wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
 609     wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
 610 
 611     return accum;
 612 
 613     cmsUNUSED_PARAMETER(info);
 614     cmsUNUSED_PARAMETER(Stride);
 615 }
 616 
 617 static
 618 cmsUInt8Number* Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 619                                       CMSREGISTER cmsUInt16Number wIn[],
 620                                       CMSREGISTER cmsUInt8Number* accum,
 621                                       CMSREGISTER cmsUInt32Number Stride)
 622 {
 623     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 624     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 625     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 626     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 627 
 628     return accum;
 629 
 630     cmsUNUSED_PARAMETER(info);
 631     cmsUNUSED_PARAMETER(Stride);
 632 }
 633 
 634 // KYMC
 635 static
 636 cmsUInt8Number* Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
 637                                  CMSREGISTER cmsUInt16Number wIn[],
 638                                  CMSREGISTER cmsUInt8Number* accum,
 639                                  CMSREGISTER cmsUInt32Number Stride)
 640 {
 641     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
 642     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 643     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
 644     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
 645 
 646     return accum;
 647 
 648     cmsUNUSED_PARAMETER(info);
 649     cmsUNUSED_PARAMETER(Stride);
 650 }
 651 
 652 static
 653 cmsUInt8Number* Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 654                                           CMSREGISTER cmsUInt16Number wIn[],
 655                                           CMSREGISTER cmsUInt8Number* accum,
 656                                           CMSREGISTER cmsUInt32Number Stride)
 657 {
 658     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
 659     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
 660     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
 661     wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
 662 
 663     return accum;
 664 
 665     cmsUNUSED_PARAMETER(info);
 666     cmsUNUSED_PARAMETER(Stride);
 667 }
 668 
 669 static
 670 cmsUInt8Number* Unroll3Words(CMSREGISTER _cmsTRANSFORM* info,
 671                              CMSREGISTER cmsUInt16Number wIn[],
 672                              CMSREGISTER cmsUInt8Number* accum,
 673                              CMSREGISTER cmsUInt32Number Stride)
 674 {
 675     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2;  // C R
 676     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2;  // M G
 677     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;  // Y B
 678 
 679     return accum;
 680 
 681     cmsUNUSED_PARAMETER(info);
 682     cmsUNUSED_PARAMETER(Stride);
 683 }
 684 
 685 static
 686 cmsUInt8Number* Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
 687                                  CMSREGISTER cmsUInt16Number wIn[],
 688                                  CMSREGISTER cmsUInt8Number* accum,
 689                                  CMSREGISTER cmsUInt32Number Stride)
 690 {
 691     wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;  // C R
 692     wIn[1] = *(cmsUInt16Number*) accum; accum+= 2;  // M G
 693     wIn[0] = *(cmsUInt16Number*) accum; accum+= 2;  // Y B
 694 
 695     return accum;
 696 
 697     cmsUNUSED_PARAMETER(info);
 698     cmsUNUSED_PARAMETER(Stride);
 699 }
 700 
 701 static
 702 cmsUInt8Number* Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
 703                                       CMSREGISTER cmsUInt16Number wIn[],
 704                                       CMSREGISTER cmsUInt8Number* accum,
 705                                       CMSREGISTER cmsUInt32Number Stride)
 706 {
 707     accum += 2; // A
 708     wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
 709     wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
 710     wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
 711 
 712     return accum;
 713 
 714     cmsUNUSED_PARAMETER(info);
 715     cmsUNUSED_PARAMETER(Stride);
 716 }
 717 
 718 static
 719 cmsUInt8Number* Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
 720                                            CMSREGISTER cmsUInt16Number wIn[],
 721                                            CMSREGISTER cmsUInt8Number* accum,
 722                                            CMSREGISTER cmsUInt32Number Stride)
 723 {
 724     accum += 2; // A
 725     wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
 726     wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
 727     wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
 728 
 729     return accum;
 730 
 731     cmsUNUSED_PARAMETER(info);
 732     cmsUNUSED_PARAMETER(Stride);
 733 }
 734 
 735 static
 736 cmsUInt8Number* Unroll1Word(CMSREGISTER _cmsTRANSFORM* info,
 737                             CMSREGISTER cmsUInt16Number wIn[],
 738                             CMSREGISTER cmsUInt8Number* accum,
 739                             CMSREGISTER cmsUInt32Number Stride)
 740 {
 741     wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2;   // L
 742 
 743     return accum;
 744 
 745     cmsUNUSED_PARAMETER(info);
 746     cmsUNUSED_PARAMETER(Stride);
 747 }
 748 
 749 static
 750 cmsUInt8Number* Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
 751                                     CMSREGISTER cmsUInt16Number wIn[],
 752                                     CMSREGISTER cmsUInt8Number* accum,
 753                                     CMSREGISTER cmsUInt32Number Stride)
 754 {
 755     wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
 756 
 757     return accum;
 758 
 759     cmsUNUSED_PARAMETER(info);
 760     cmsUNUSED_PARAMETER(Stride);
 761 }
 762 
 763 static
 764 cmsUInt8Number* Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM* info,
 765                                  CMSREGISTER cmsUInt16Number wIn[],
 766                                  CMSREGISTER cmsUInt8Number* accum,
 767                                  CMSREGISTER cmsUInt32Number Stride)
 768 {
 769     wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
 770 
 771     accum += 8;
 772 
 773     return accum;
 774 
 775     cmsUNUSED_PARAMETER(info);
 776     cmsUNUSED_PARAMETER(Stride);
 777 }
 778 
 779 static
 780 cmsUInt8Number* Unroll2Words(CMSREGISTER _cmsTRANSFORM* info,
 781                                      CMSREGISTER cmsUInt16Number wIn[],
 782                                      CMSREGISTER cmsUInt8Number* accum,
 783                                      CMSREGISTER cmsUInt32Number Stride)
 784 {
 785     wIn[0] = *(cmsUInt16Number*) accum; accum += 2;    // ch1
 786     wIn[1] = *(cmsUInt16Number*) accum; accum += 2;    // ch2
 787 
 788     return accum;
 789 
 790     cmsUNUSED_PARAMETER(info);
 791     cmsUNUSED_PARAMETER(Stride);
 792 }
 793 
 794 
 795 // This is a conversion of Lab double to 16 bits
 796 static
 797 cmsUInt8Number* UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
 798                                     CMSREGISTER cmsUInt16Number wIn[],
 799                                     CMSREGISTER cmsUInt8Number* accum,
 800                                     CMSREGISTER cmsUInt32Number  Stride)
 801 {
 802     if (T_PLANAR(info -> InputFormat)) {
 803 
 804         cmsCIELab Lab;
 805         cmsUInt8Number* pos_L;
 806         cmsUInt8Number* pos_a;
 807         cmsUInt8Number* pos_b;
 808 
 809         pos_L = accum;
 810         pos_a = accum + Stride;
 811         pos_b = accum + Stride * 2;
 812 
 813         Lab.L = *(cmsFloat64Number*) pos_L;
 814         Lab.a = *(cmsFloat64Number*) pos_a;
 815         Lab.b = *(cmsFloat64Number*) pos_b;
 816 
 817         cmsFloat2LabEncoded(wIn, &Lab);
 818         return accum + sizeof(cmsFloat64Number);
 819     }
 820     else {
 821 
 822         cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
 823         accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
 824         return accum;
 825     }
 826 }
 827 
 828 
 829 // This is a conversion of Lab float to 16 bits
 830 static
 831 cmsUInt8Number* UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
 832                                     CMSREGISTER cmsUInt16Number wIn[],
 833                                     CMSREGISTER cmsUInt8Number* accum,
 834                                     CMSREGISTER cmsUInt32Number  Stride)
 835 {
 836     cmsCIELab Lab;
 837 
 838     if (T_PLANAR(info -> InputFormat)) {
 839 
 840         cmsUInt8Number* pos_L;
 841         cmsUInt8Number* pos_a;
 842         cmsUInt8Number* pos_b;
 843 
 844         pos_L = accum;
 845         pos_a = accum + Stride;
 846         pos_b = accum + Stride * 2;
 847 
 848         Lab.L = *(cmsFloat32Number*)pos_L;
 849         Lab.a = *(cmsFloat32Number*)pos_a;
 850         Lab.b = *(cmsFloat32Number*)pos_b;
 851 
 852         cmsFloat2LabEncoded(wIn, &Lab);
 853         return accum + sizeof(cmsFloat32Number);
 854     }
 855     else {
 856 
 857         Lab.L = ((cmsFloat32Number*) accum)[0];
 858         Lab.a = ((cmsFloat32Number*) accum)[1];
 859         Lab.b = ((cmsFloat32Number*) accum)[2];
 860 
 861         cmsFloat2LabEncoded(wIn, &Lab);
 862         accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
 863         return accum;
 864     }
 865 }
 866 
 867 // This is a conversion of XYZ double to 16 bits
 868 static
 869 cmsUInt8Number* UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
 870                                     CMSREGISTER cmsUInt16Number wIn[],
 871                                     CMSREGISTER cmsUInt8Number* accum,
 872                                     CMSREGISTER cmsUInt32Number Stride)
 873 {
 874     if (T_PLANAR(info -> InputFormat)) {
 875 
 876         cmsCIEXYZ XYZ;
 877         cmsUInt8Number* pos_X;
 878         cmsUInt8Number* pos_Y;
 879         cmsUInt8Number* pos_Z;
 880 
 881         pos_X = accum;
 882         pos_Y = accum + Stride;
 883         pos_Z = accum + Stride * 2;
 884 
 885         XYZ.X = *(cmsFloat64Number*)pos_X;
 886         XYZ.Y = *(cmsFloat64Number*)pos_Y;
 887         XYZ.Z = *(cmsFloat64Number*)pos_Z;
 888 
 889         cmsFloat2XYZEncoded(wIn, &XYZ);
 890 
 891         return accum + sizeof(cmsFloat64Number);
 892 
 893     }
 894 
 895     else {
 896         cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
 897         accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
 898 
 899         return accum;
 900     }
 901 }
 902 
 903 // This is a conversion of XYZ float to 16 bits
 904 static
 905 cmsUInt8Number* UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
 906                                    CMSREGISTER cmsUInt16Number wIn[],
 907                                    CMSREGISTER cmsUInt8Number* accum,
 908                                    CMSREGISTER cmsUInt32Number Stride)
 909 {
 910     if (T_PLANAR(info -> InputFormat)) {
 911 
 912         cmsCIEXYZ XYZ;
 913         cmsUInt8Number* pos_X;
 914         cmsUInt8Number* pos_Y;
 915         cmsUInt8Number* pos_Z;
 916 
 917         pos_X = accum;
 918         pos_Y = accum + Stride;
 919         pos_Z = accum + Stride * 2;
 920 
 921         XYZ.X = *(cmsFloat32Number*)pos_X;
 922         XYZ.Y = *(cmsFloat32Number*)pos_Y;
 923         XYZ.Z = *(cmsFloat32Number*)pos_Z;
 924 
 925         cmsFloat2XYZEncoded(wIn, &XYZ);
 926 
 927         return accum + sizeof(cmsFloat32Number);
 928 


 965      default: return FALSE;
 966     }
 967 }
 968 
 969 // Return the size in bytes of a given formatter
 970 static
 971 cmsUInt32Number PixelSize(cmsUInt32Number Format)
 972 {
 973     cmsUInt32Number fmt_bytes = T_BYTES(Format);
 974 
 975     // For double, the T_BYTES field is zero
 976     if (fmt_bytes == 0)
 977         return sizeof(cmsUInt64Number);
 978 
 979     // Otherwise, it is already correct for all formats
 980     return fmt_bytes;
 981 }
 982 
 983 // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
 984 static
 985 cmsUInt8Number* UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
 986                                 CMSREGISTER cmsUInt16Number wIn[],
 987                                 CMSREGISTER cmsUInt8Number* accum,
 988                                 CMSREGISTER cmsUInt32Number Stride)
 989 {
 990 
 991     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
 992     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
 993     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
 994     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
 995     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
 996     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
 997     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
 998     cmsFloat64Number v;
 999     cmsUInt16Number  vi;
1000     cmsUInt32Number i, start = 0;
1001     cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1002 
1003 
1004     Stride /= PixelSize(info->InputFormat);
1005 
1006     if (ExtraFirst)
1007             start = Extra;
1008 


1023         wIn[index] = vi;
1024     }
1025 
1026 
1027     if (Extra == 0 && SwapFirst) {
1028         cmsUInt16Number tmp = wIn[0];
1029 
1030         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1031         wIn[nChan-1] = tmp;
1032     }
1033 
1034     if (T_PLANAR(info -> InputFormat))
1035         return accum + sizeof(cmsFloat64Number);
1036     else
1037         return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
1038 }
1039 
1040 
1041 
1042 static
1043 cmsUInt8Number* UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
1044                                 CMSREGISTER cmsUInt16Number wIn[],
1045                                 CMSREGISTER cmsUInt8Number* accum,
1046                                 CMSREGISTER cmsUInt32Number Stride)
1047 {
1048 
1049     cmsUInt32Number nChan  = T_CHANNELS(info -> InputFormat);
1050     cmsUInt32Number DoSwap   = T_DOSWAP(info ->InputFormat);
1051     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
1052     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
1053     cmsUInt32Number Extra   = T_EXTRA(info -> InputFormat);
1054     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1055     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
1056     cmsFloat32Number v;
1057     cmsUInt16Number  vi;
1058     cmsUInt32Number i, start = 0;
1059     cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
1060 
1061     Stride /= PixelSize(info->InputFormat);
1062 
1063     if (ExtraFirst)
1064             start = Extra;
1065 
1066     for (i=0; i < nChan; i++) {


1082 
1083 
1084     if (Extra == 0 && SwapFirst) {
1085         cmsUInt16Number tmp = wIn[0];
1086 
1087         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
1088         wIn[nChan-1] = tmp;
1089     }
1090 
1091     if (T_PLANAR(info -> InputFormat))
1092         return accum + sizeof(cmsFloat32Number);
1093     else
1094         return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
1095 }
1096 
1097 
1098 
1099 
1100 // For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
1101 static
1102 cmsUInt8Number* UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM* info,
1103                                   CMSREGISTER cmsUInt16Number wIn[],
1104                                   CMSREGISTER cmsUInt8Number* accum,
1105                                   CMSREGISTER cmsUInt32Number Stride)
1106 {
1107     cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
1108 
1109     wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
1110 
1111     return accum + sizeof(cmsFloat64Number);
1112 
1113     cmsUNUSED_PARAMETER(info);
1114     cmsUNUSED_PARAMETER(Stride);
1115 }
1116 
1117 //-------------------------------------------------------------------------------------------------------------------
1118 
1119 // For anything going from cmsFloat32Number
1120 static
1121 cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
1122                                     cmsFloat32Number wIn[],
1123                                     cmsUInt8Number* accum,
1124                                     cmsUInt32Number Stride)
1125 {


1335     }
1336     else {
1337 
1338         wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
1339         wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
1340         wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
1341 
1342         accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
1343         return accum;
1344     }
1345 }
1346 
1347 
1348 
1349 // Packing routines -----------------------------------------------------------------------------------------------------------
1350 
1351 
1352 // Generic chunky for byte
1353 
1354 static
1355 cmsUInt8Number* PackAnyBytes(CMSREGISTER _cmsTRANSFORM* info,
1356                              CMSREGISTER cmsUInt16Number wOut[],
1357                              CMSREGISTER cmsUInt8Number* output,
1358                              CMSREGISTER cmsUInt32Number Stride)
1359 {
1360     cmsUInt32Number nChan  = T_CHANNELS(info -> OutputFormat);
1361     cmsUInt32Number DoSwap   = T_DOSWAP(info ->OutputFormat);
1362     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1363     cmsUInt32Number Extra   = T_EXTRA(info -> OutputFormat);
1364     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
1365     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1366     cmsUInt8Number* swap1;
1367     cmsUInt8Number v = 0;
1368     cmsUInt32Number i;
1369 
1370     swap1 = output;
1371 
1372     if (ExtraFirst) {
1373         output += Extra;
1374     }
1375 
1376     for (i=0; i < nChan; i++) {
1377 
1378         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;


1387 
1388     if (!ExtraFirst) {
1389         output += Extra;
1390     }
1391 
1392     if (Extra == 0 && SwapFirst) {
1393 
1394         memmove(swap1 + 1, swap1, nChan-1);
1395         *swap1 = v;
1396     }
1397 
1398 
1399     return output;
1400 
1401     cmsUNUSED_PARAMETER(Stride);
1402 }
1403 
1404 
1405 
1406 static
1407 cmsUInt8Number* PackAnyWords(CMSREGISTER _cmsTRANSFORM* info,
1408                              CMSREGISTER cmsUInt16Number wOut[],
1409                              CMSREGISTER cmsUInt8Number* output,
1410                              CMSREGISTER cmsUInt32Number Stride)
1411 {
1412     cmsUInt32Number nChan  = T_CHANNELS(info -> OutputFormat);
1413     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
1414     cmsUInt32Number DoSwap   = T_DOSWAP(info ->OutputFormat);
1415     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1416     cmsUInt32Number Extra   = T_EXTRA(info -> OutputFormat);
1417     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
1418     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
1419     cmsUInt16Number* swap1;
1420     cmsUInt16Number v = 0;
1421     cmsUInt32Number i;
1422 
1423     swap1 = (cmsUInt16Number*) output;
1424 
1425     if (ExtraFirst) {
1426         output += Extra * sizeof(cmsUInt16Number);
1427     }
1428 
1429     for (i=0; i < nChan; i++) {
1430 


1444     }
1445 
1446     if (!ExtraFirst) {
1447         output += Extra * sizeof(cmsUInt16Number);
1448     }
1449 
1450     if (Extra == 0 && SwapFirst) {
1451 
1452         memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
1453         *swap1 = v;
1454     }
1455 
1456 
1457     return output;
1458 
1459     cmsUNUSED_PARAMETER(Stride);
1460 }
1461 
1462 
1463 static
1464 cmsUInt8Number* PackPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
1465                                 CMSREGISTER cmsUInt16Number wOut[],
1466                                 CMSREGISTER cmsUInt8Number* output,
1467                                 CMSREGISTER cmsUInt32Number Stride)
1468 {
1469     cmsUInt32Number nChan     = T_CHANNELS(info -> OutputFormat);
1470     cmsUInt32Number DoSwap    = T_DOSWAP(info ->OutputFormat);
1471     cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->OutputFormat);
1472     cmsUInt32Number Reverse   = T_FLAVOR(info ->OutputFormat);
1473     cmsUInt32Number i;
1474     cmsUInt8Number* Init = output;
1475 
1476 
1477     if (DoSwap ^ SwapFirst) {
1478         output += T_EXTRA(info -> OutputFormat) * Stride;
1479     }
1480 
1481 
1482     for (i=0; i < nChan; i++) {
1483 
1484         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1485         cmsUInt8Number v = FROM_16_TO_8(wOut[index]);
1486 
1487         *(cmsUInt8Number*)  output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v);
1488         output += Stride;
1489     }
1490 
1491     return (Init + 1);
1492 
1493     cmsUNUSED_PARAMETER(Stride);
1494 }
1495 
1496 
1497 static
1498 cmsUInt8Number* PackPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
1499                                 CMSREGISTER cmsUInt16Number wOut[],
1500                                 CMSREGISTER cmsUInt8Number* output,
1501                                 CMSREGISTER cmsUInt32Number Stride)
1502 {
1503     cmsUInt32Number nChan      = T_CHANNELS(info -> OutputFormat);
1504     cmsUInt32Number DoSwap     = T_DOSWAP(info ->OutputFormat);
1505     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
1506     cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat);
1507     cmsUInt32Number i;
1508     cmsUInt8Number* Init = output;
1509     cmsUInt16Number v;
1510 
1511     if (DoSwap) {
1512         output += T_EXTRA(info -> OutputFormat) * Stride;
1513     }
1514 
1515     for (i=0; i < nChan; i++) {
1516 
1517         cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
1518 
1519         v = wOut[index];
1520 
1521         if (SwapEndian)
1522             v = CHANGE_ENDIAN(v);
1523 
1524         if (Reverse)
1525             v =  REVERSE_FLAVOR_16(v);
1526 
1527         *(cmsUInt16Number*) output = v;
1528         output += Stride;
1529     }
1530 
1531     return (Init + sizeof(cmsUInt16Number));
1532 }
1533 
1534 // CMYKcm (unrolled for speed)
1535 
1536 static
1537 cmsUInt8Number* Pack6Bytes(CMSREGISTER _cmsTRANSFORM* info,
1538                            CMSREGISTER cmsUInt16Number wOut[],
1539                            CMSREGISTER cmsUInt8Number* output,
1540                            CMSREGISTER cmsUInt32Number Stride)
1541 {
1542     *output++ = FROM_16_TO_8(wOut[0]);
1543     *output++ = FROM_16_TO_8(wOut[1]);
1544     *output++ = FROM_16_TO_8(wOut[2]);
1545     *output++ = FROM_16_TO_8(wOut[3]);
1546     *output++ = FROM_16_TO_8(wOut[4]);
1547     *output++ = FROM_16_TO_8(wOut[5]);
1548 
1549     return output;
1550 
1551     cmsUNUSED_PARAMETER(info);
1552     cmsUNUSED_PARAMETER(Stride);
1553 }
1554 
1555 // KCMYcm
1556 
1557 static
1558 cmsUInt8Number* Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
1559                                CMSREGISTER cmsUInt16Number wOut[],
1560                                CMSREGISTER cmsUInt8Number* output,
1561                                CMSREGISTER cmsUInt32Number Stride)
1562 {
1563     *output++ = FROM_16_TO_8(wOut[5]);
1564     *output++ = FROM_16_TO_8(wOut[4]);
1565     *output++ = FROM_16_TO_8(wOut[3]);
1566     *output++ = FROM_16_TO_8(wOut[2]);
1567     *output++ = FROM_16_TO_8(wOut[1]);
1568     *output++ = FROM_16_TO_8(wOut[0]);
1569 
1570     return output;
1571 
1572     cmsUNUSED_PARAMETER(info);
1573     cmsUNUSED_PARAMETER(Stride);
1574 }
1575 
1576 // CMYKcm
1577 static
1578 cmsUInt8Number* Pack6Words(CMSREGISTER _cmsTRANSFORM* info,
1579                            CMSREGISTER cmsUInt16Number wOut[],
1580                            CMSREGISTER cmsUInt8Number* output,
1581                            CMSREGISTER cmsUInt32Number Stride)
1582 {
1583     *(cmsUInt16Number*) output = wOut[0];
1584     output+= 2;
1585     *(cmsUInt16Number*) output = wOut[1];
1586     output+= 2;
1587     *(cmsUInt16Number*) output = wOut[2];
1588     output+= 2;
1589     *(cmsUInt16Number*) output = wOut[3];
1590     output+= 2;
1591     *(cmsUInt16Number*) output = wOut[4];
1592     output+= 2;
1593     *(cmsUInt16Number*) output = wOut[5];
1594     output+= 2;
1595 
1596     return output;
1597 
1598     cmsUNUSED_PARAMETER(info);
1599     cmsUNUSED_PARAMETER(Stride);
1600 }
1601 
1602 // KCMYcm
1603 static
1604 cmsUInt8Number* Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
1605                                CMSREGISTER cmsUInt16Number wOut[],
1606                                CMSREGISTER cmsUInt8Number* output,
1607                                CMSREGISTER cmsUInt32Number Stride)
1608 {
1609     *(cmsUInt16Number*) output = wOut[5];
1610     output+= 2;
1611     *(cmsUInt16Number*) output = wOut[4];
1612     output+= 2;
1613     *(cmsUInt16Number*) output = wOut[3];
1614     output+= 2;
1615     *(cmsUInt16Number*) output = wOut[2];
1616     output+= 2;
1617     *(cmsUInt16Number*) output = wOut[1];
1618     output+= 2;
1619     *(cmsUInt16Number*) output = wOut[0];
1620     output+= 2;
1621 
1622     return output;
1623 
1624     cmsUNUSED_PARAMETER(info);
1625     cmsUNUSED_PARAMETER(Stride);
1626 }
1627 
1628 
1629 static
1630 cmsUInt8Number* Pack4Bytes(CMSREGISTER _cmsTRANSFORM* info,
1631                            CMSREGISTER cmsUInt16Number wOut[],
1632                            CMSREGISTER cmsUInt8Number* output,
1633                            CMSREGISTER cmsUInt32Number Stride)
1634 {
1635     *output++ = FROM_16_TO_8(wOut[0]);
1636     *output++ = FROM_16_TO_8(wOut[1]);
1637     *output++ = FROM_16_TO_8(wOut[2]);
1638     *output++ = FROM_16_TO_8(wOut[3]);
1639 
1640     return output;
1641 
1642     cmsUNUSED_PARAMETER(info);
1643     cmsUNUSED_PARAMETER(Stride);
1644 }
1645 
1646 static
1647 cmsUInt8Number* Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
1648                                   CMSREGISTER cmsUInt16Number wOut[],
1649                                   CMSREGISTER cmsUInt8Number* output,
1650                                   CMSREGISTER cmsUInt32Number Stride)
1651 {
1652     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
1653     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
1654     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
1655     *output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
1656 
1657     return output;
1658 
1659     cmsUNUSED_PARAMETER(info);
1660     cmsUNUSED_PARAMETER(Stride);
1661 }
1662 
1663 
1664 static
1665 cmsUInt8Number* Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
1666                                     CMSREGISTER cmsUInt16Number wOut[],
1667                                     CMSREGISTER cmsUInt8Number* output,
1668                                     CMSREGISTER cmsUInt32Number Stride)
1669 {
1670     *output++ = FROM_16_TO_8(wOut[3]);
1671     *output++ = FROM_16_TO_8(wOut[0]);
1672     *output++ = FROM_16_TO_8(wOut[1]);
1673     *output++ = FROM_16_TO_8(wOut[2]);
1674 
1675     return output;
1676 
1677     cmsUNUSED_PARAMETER(info);
1678     cmsUNUSED_PARAMETER(Stride);
1679 }
1680 
1681 // ABGR
1682 static
1683 cmsUInt8Number* Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
1684                                CMSREGISTER cmsUInt16Number wOut[],
1685                                CMSREGISTER cmsUInt8Number* output,
1686                                CMSREGISTER cmsUInt32Number Stride)
1687 {
1688     *output++ = FROM_16_TO_8(wOut[3]);
1689     *output++ = FROM_16_TO_8(wOut[2]);
1690     *output++ = FROM_16_TO_8(wOut[1]);
1691     *output++ = FROM_16_TO_8(wOut[0]);
1692 
1693     return output;
1694 
1695     cmsUNUSED_PARAMETER(info);
1696     cmsUNUSED_PARAMETER(Stride);
1697 }
1698 
1699 static
1700 cmsUInt8Number* Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
1701                                         CMSREGISTER cmsUInt16Number wOut[],
1702                                         CMSREGISTER cmsUInt8Number* output,
1703                                         CMSREGISTER cmsUInt32Number Stride)
1704 {
1705     *output++ = FROM_16_TO_8(wOut[2]);
1706     *output++ = FROM_16_TO_8(wOut[1]);
1707     *output++ = FROM_16_TO_8(wOut[0]);
1708     *output++ = FROM_16_TO_8(wOut[3]);
1709 
1710     return output;
1711 
1712     cmsUNUSED_PARAMETER(info);
1713     cmsUNUSED_PARAMETER(Stride);
1714 }
1715 
1716 static
1717 cmsUInt8Number* Pack4Words(CMSREGISTER _cmsTRANSFORM* info,
1718                            CMSREGISTER cmsUInt16Number wOut[],
1719                            CMSREGISTER cmsUInt8Number* output,
1720                            CMSREGISTER cmsUInt32Number Stride)
1721 {
1722     *(cmsUInt16Number*) output = wOut[0];
1723     output+= 2;
1724     *(cmsUInt16Number*) output = wOut[1];
1725     output+= 2;
1726     *(cmsUInt16Number*) output = wOut[2];
1727     output+= 2;
1728     *(cmsUInt16Number*) output = wOut[3];
1729     output+= 2;
1730 
1731     return output;
1732 
1733     cmsUNUSED_PARAMETER(info);
1734     cmsUNUSED_PARAMETER(Stride);
1735 }
1736 
1737 static
1738 cmsUInt8Number* Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
1739                                   CMSREGISTER cmsUInt16Number wOut[],
1740                                   CMSREGISTER cmsUInt8Number* output,
1741                                   CMSREGISTER cmsUInt32Number Stride)
1742 {
1743     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
1744     output+= 2;
1745     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
1746     output+= 2;
1747     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
1748     output+= 2;
1749     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
1750     output+= 2;
1751 
1752     return output;
1753 
1754     cmsUNUSED_PARAMETER(info);
1755     cmsUNUSED_PARAMETER(Stride);
1756 }
1757 
1758 // ABGR
1759 static
1760 cmsUInt8Number* Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
1761                                CMSREGISTER cmsUInt16Number wOut[],
1762                                CMSREGISTER cmsUInt8Number* output,
1763                                CMSREGISTER cmsUInt32Number Stride)
1764 {
1765     *(cmsUInt16Number*) output = wOut[3];
1766     output+= 2;
1767     *(cmsUInt16Number*) output = wOut[2];
1768     output+= 2;
1769     *(cmsUInt16Number*) output = wOut[1];
1770     output+= 2;
1771     *(cmsUInt16Number*) output = wOut[0];
1772     output+= 2;
1773 
1774     return output;
1775 
1776     cmsUNUSED_PARAMETER(info);
1777     cmsUNUSED_PARAMETER(Stride);
1778 }
1779 
1780 // CMYK
1781 static
1782 cmsUInt8Number* Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
1783                                     CMSREGISTER cmsUInt16Number wOut[],
1784                                     CMSREGISTER cmsUInt8Number* output,
1785                                     CMSREGISTER cmsUInt32Number Stride)
1786 {
1787     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1788     output+= 2;
1789     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1790     output+= 2;
1791     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1792     output+= 2;
1793     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
1794     output+= 2;
1795 
1796     return output;
1797 
1798     cmsUNUSED_PARAMETER(info);
1799     cmsUNUSED_PARAMETER(Stride);
1800 }
1801 
1802 
1803 static
1804 cmsUInt8Number* PackLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
1805                             CMSREGISTER cmsUInt16Number wOut[],
1806                             CMSREGISTER cmsUInt8Number* output,
1807                             CMSREGISTER cmsUInt32Number Stride)
1808 {
1809     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1810     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1811     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1812 
1813     return output;
1814 
1815     cmsUNUSED_PARAMETER(info);
1816     cmsUNUSED_PARAMETER(Stride);
1817 }
1818 
1819 static
1820 cmsUInt8Number* PackALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
1821                              CMSREGISTER cmsUInt16Number wOut[],
1822                              CMSREGISTER cmsUInt8Number* output,
1823                              CMSREGISTER cmsUInt32Number Stride)
1824 {
1825     output++;
1826     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
1827     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
1828     *output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
1829 
1830     return output;
1831 
1832     cmsUNUSED_PARAMETER(info);
1833     cmsUNUSED_PARAMETER(Stride);
1834 }
1835 
1836 static
1837 cmsUInt8Number* PackLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
1838                              CMSREGISTER cmsUInt16Number wOut[],
1839                              CMSREGISTER cmsUInt8Number* output,
1840                              CMSREGISTER cmsUInt32Number Stride)
1841 {
1842     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
1843     output += 2;
1844     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
1845     output += 2;
1846     *(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
1847     output += 2;
1848 
1849     return output;
1850 
1851     cmsUNUSED_PARAMETER(info);
1852     cmsUNUSED_PARAMETER(Stride);
1853 }
1854 
1855 static
1856 cmsUInt8Number* Pack3Bytes(CMSREGISTER _cmsTRANSFORM* info,
1857                            CMSREGISTER cmsUInt16Number wOut[],
1858                            CMSREGISTER cmsUInt8Number* output,
1859                            CMSREGISTER cmsUInt32Number Stride)
1860 {
1861     *output++ = FROM_16_TO_8(wOut[0]);
1862     *output++ = FROM_16_TO_8(wOut[1]);
1863     *output++ = FROM_16_TO_8(wOut[2]);
1864 
1865     return output;
1866 
1867     cmsUNUSED_PARAMETER(info);
1868     cmsUNUSED_PARAMETER(Stride);
1869 }
1870 
1871 static
1872 cmsUInt8Number* Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM* info,
1873                                     CMSREGISTER cmsUInt16Number wOut[],
1874                                     CMSREGISTER cmsUInt8Number* output,
1875                                     CMSREGISTER cmsUInt32Number Stride)
1876 {
1877     *output++ = (wOut[0] & 0xFFU);
1878     *output++ = (wOut[1] & 0xFFU);
1879     *output++ = (wOut[2] & 0xFFU);
1880 
1881     return output;
1882 
1883     cmsUNUSED_PARAMETER(info);
1884     cmsUNUSED_PARAMETER(Stride);
1885 }
1886 
1887 static
1888 cmsUInt8Number* Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
1889                                CMSREGISTER cmsUInt16Number wOut[],
1890                                CMSREGISTER cmsUInt8Number* output,
1891                                CMSREGISTER cmsUInt32Number Stride)
1892 {
1893     *output++ = FROM_16_TO_8(wOut[2]);
1894     *output++ = FROM_16_TO_8(wOut[1]);
1895     *output++ = FROM_16_TO_8(wOut[0]);
1896 
1897     return output;
1898 
1899     cmsUNUSED_PARAMETER(info);
1900     cmsUNUSED_PARAMETER(Stride);
1901 }
1902 
1903 static
1904 cmsUInt8Number* Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
1905                                         CMSREGISTER cmsUInt16Number wOut[],
1906                                         CMSREGISTER cmsUInt8Number* output,
1907                                         CMSREGISTER cmsUInt32Number Stride)
1908 {
1909     *output++ = (wOut[2] & 0xFFU);
1910     *output++ = (wOut[1] & 0xFFU);
1911     *output++ = (wOut[0] & 0xFFU);
1912 
1913     return output;
1914 
1915     cmsUNUSED_PARAMETER(info);
1916     cmsUNUSED_PARAMETER(Stride);
1917 }
1918 
1919 
1920 static
1921 cmsUInt8Number* Pack3Words(CMSREGISTER _cmsTRANSFORM* info,
1922                            CMSREGISTER cmsUInt16Number wOut[],
1923                            CMSREGISTER cmsUInt8Number* output,
1924                            CMSREGISTER cmsUInt32Number Stride)
1925 {
1926     *(cmsUInt16Number*) output = wOut[0];
1927     output+= 2;
1928     *(cmsUInt16Number*) output = wOut[1];
1929     output+= 2;
1930     *(cmsUInt16Number*) output = wOut[2];
1931     output+= 2;
1932 
1933     return output;
1934 
1935     cmsUNUSED_PARAMETER(info);
1936     cmsUNUSED_PARAMETER(Stride);
1937 }
1938 
1939 static
1940 cmsUInt8Number* Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
1941                                CMSREGISTER cmsUInt16Number wOut[],
1942                                CMSREGISTER cmsUInt8Number* output,
1943                                CMSREGISTER cmsUInt32Number Stride)
1944 {
1945     *(cmsUInt16Number*) output = wOut[2];
1946     output+= 2;
1947     *(cmsUInt16Number*) output = wOut[1];
1948     output+= 2;
1949     *(cmsUInt16Number*) output = wOut[0];
1950     output+= 2;
1951 
1952     return output;
1953 
1954     cmsUNUSED_PARAMETER(info);
1955     cmsUNUSED_PARAMETER(Stride);
1956 }
1957 
1958 static
1959 cmsUInt8Number* Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
1960                                     CMSREGISTER cmsUInt16Number wOut[],
1961                                     CMSREGISTER cmsUInt8Number* output,
1962                                     CMSREGISTER cmsUInt32Number Stride)
1963 {
1964     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
1965     output+= 2;
1966     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
1967     output+= 2;
1968     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
1969     output+= 2;
1970 
1971     return output;
1972 
1973     cmsUNUSED_PARAMETER(info);
1974     cmsUNUSED_PARAMETER(Stride);
1975 }
1976 
1977 static
1978 cmsUInt8Number* Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
1979                                    CMSREGISTER cmsUInt16Number wOut[],
1980                                    CMSREGISTER cmsUInt8Number* output,
1981                                    CMSREGISTER cmsUInt32Number Stride)
1982 {
1983     *output++ = FROM_16_TO_8(wOut[0]);
1984     *output++ = FROM_16_TO_8(wOut[1]);
1985     *output++ = FROM_16_TO_8(wOut[2]);
1986     output++;
1987 
1988     return output;
1989 
1990     cmsUNUSED_PARAMETER(info);
1991     cmsUNUSED_PARAMETER(Stride);
1992 }
1993 
1994 static
1995 cmsUInt8Number* Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM* info,
1996                                             CMSREGISTER cmsUInt16Number wOut[],
1997                                             CMSREGISTER cmsUInt8Number* output,
1998                                             CMSREGISTER cmsUInt32Number Stride)
1999 {
2000     *output++ = (wOut[0] & 0xFFU);
2001     *output++ = (wOut[1] & 0xFFU);
2002     *output++ = (wOut[2] & 0xFFU);
2003     output++;
2004 
2005     return output;
2006 
2007     cmsUNUSED_PARAMETER(info);
2008     cmsUNUSED_PARAMETER(Stride);
2009 }
2010 
2011 
2012 static
2013 cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2014                                             CMSREGISTER cmsUInt16Number wOut[],
2015                                             CMSREGISTER cmsUInt8Number* output,
2016                                             CMSREGISTER cmsUInt32Number Stride)
2017 {
2018     output++;
2019     *output++ = FROM_16_TO_8(wOut[0]);
2020     *output++ = FROM_16_TO_8(wOut[1]);
2021     *output++ = FROM_16_TO_8(wOut[2]);
2022 
2023     return output;
2024 
2025     cmsUNUSED_PARAMETER(info);
2026     cmsUNUSED_PARAMETER(Stride);
2027 }
2028 
2029 static
2030 cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
2031                                                      CMSREGISTER cmsUInt16Number wOut[],
2032                                                      CMSREGISTER cmsUInt8Number* output,
2033                                                      CMSREGISTER cmsUInt32Number Stride)
2034 {
2035     output++;
2036     *output++ = (wOut[0] & 0xFFU);
2037     *output++ = (wOut[1] & 0xFFU);
2038     *output++ = (wOut[2] & 0xFFU);
2039 
2040     return output;
2041 
2042     cmsUNUSED_PARAMETER(info);
2043     cmsUNUSED_PARAMETER(Stride);
2044 }
2045 
2046 static
2047 cmsUInt8Number* Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
2048                                        CMSREGISTER cmsUInt16Number wOut[],
2049                                        CMSREGISTER cmsUInt8Number* output,
2050                                        CMSREGISTER cmsUInt32Number Stride)
2051 {
2052     output++;
2053     *output++ = FROM_16_TO_8(wOut[2]);
2054     *output++ = FROM_16_TO_8(wOut[1]);
2055     *output++ = FROM_16_TO_8(wOut[0]);
2056 
2057     return output;
2058 
2059     cmsUNUSED_PARAMETER(info);
2060     cmsUNUSED_PARAMETER(Stride);
2061 }
2062 
2063 static
2064 cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
2065                                                 CMSREGISTER cmsUInt16Number wOut[],
2066                                                 CMSREGISTER cmsUInt8Number* output,
2067                                                 CMSREGISTER cmsUInt32Number Stride)
2068 {
2069     output++;
2070     *output++ = (wOut[2] & 0xFFU);
2071     *output++ = (wOut[1] & 0xFFU);
2072     *output++ = (wOut[0] & 0xFFU);
2073 
2074     return output;
2075 
2076     cmsUNUSED_PARAMETER(info);
2077     cmsUNUSED_PARAMETER(Stride);
2078 }
2079 
2080 
2081 static
2082 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2083                                                 CMSREGISTER cmsUInt16Number wOut[],
2084                                                 CMSREGISTER cmsUInt8Number* output,
2085                                                 CMSREGISTER cmsUInt32Number Stride)
2086 {
2087     *output++ = FROM_16_TO_8(wOut[2]);
2088     *output++ = FROM_16_TO_8(wOut[1]);
2089     *output++ = FROM_16_TO_8(wOut[0]);
2090     output++;
2091 
2092     return output;
2093 
2094     cmsUNUSED_PARAMETER(info);
2095     cmsUNUSED_PARAMETER(Stride);
2096 }
2097 
2098 static
2099 cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
2100                                                          CMSREGISTER cmsUInt16Number wOut[],
2101                                                          CMSREGISTER cmsUInt8Number* output,
2102                                                          CMSREGISTER cmsUInt32Number Stride)
2103 {
2104     *output++ = (wOut[2] & 0xFFU);
2105     *output++ = (wOut[1] & 0xFFU);
2106     *output++ = (wOut[0] & 0xFFU);
2107     output++;
2108 
2109     return output;
2110 
2111     cmsUNUSED_PARAMETER(info);
2112     cmsUNUSED_PARAMETER(Stride);
2113 }
2114 
2115 static
2116 cmsUInt8Number* Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
2117                                    CMSREGISTER cmsUInt16Number wOut[],
2118                                    CMSREGISTER cmsUInt8Number* output,
2119                                    CMSREGISTER cmsUInt32Number Stride)
2120 {
2121     *(cmsUInt16Number*) output = wOut[0];
2122     output+= 2;
2123     *(cmsUInt16Number*) output = wOut[1];
2124     output+= 2;
2125     *(cmsUInt16Number*) output = wOut[2];
2126     output+= 2;
2127     output+= 2;
2128 
2129     return output;
2130 
2131     cmsUNUSED_PARAMETER(info);
2132     cmsUNUSED_PARAMETER(Stride);
2133 }
2134 
2135 static
2136 cmsUInt8Number* Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
2137                                        CMSREGISTER cmsUInt16Number wOut[],
2138                                        CMSREGISTER cmsUInt8Number* output,
2139                                        CMSREGISTER cmsUInt32Number Stride)
2140 {
2141     output+= 2;
2142     *(cmsUInt16Number*) output = wOut[2];
2143     output+= 2;
2144     *(cmsUInt16Number*) output = wOut[1];
2145     output+= 2;
2146     *(cmsUInt16Number*) output = wOut[0];
2147     output+= 2;
2148 
2149     return output;
2150 
2151     cmsUNUSED_PARAMETER(info);
2152     cmsUNUSED_PARAMETER(Stride);
2153 }
2154 
2155 
2156 static
2157 cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2158                                             CMSREGISTER cmsUInt16Number wOut[],
2159                                             CMSREGISTER cmsUInt8Number* output,
2160                                             CMSREGISTER cmsUInt32Number Stride)
2161 {
2162     output+= 2;
2163     *(cmsUInt16Number*) output = wOut[0];
2164     output+= 2;
2165     *(cmsUInt16Number*) output = wOut[1];
2166     output+= 2;
2167     *(cmsUInt16Number*) output = wOut[2];
2168     output+= 2;
2169 
2170     return output;
2171 
2172     cmsUNUSED_PARAMETER(info);
2173     cmsUNUSED_PARAMETER(Stride);
2174 }
2175 
2176 
2177 static
2178 cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2179                                                 CMSREGISTER cmsUInt16Number wOut[],
2180                                                 CMSREGISTER cmsUInt8Number* output,
2181                                                 CMSREGISTER cmsUInt32Number Stride)
2182 {
2183     *(cmsUInt16Number*) output = wOut[2];
2184     output+= 2;
2185     *(cmsUInt16Number*) output = wOut[1];
2186     output+= 2;
2187     *(cmsUInt16Number*) output = wOut[0];
2188     output+= 2;
2189     output+= 2;
2190 
2191     return output;
2192 
2193     cmsUNUSED_PARAMETER(info);
2194     cmsUNUSED_PARAMETER(Stride);
2195 }
2196 
2197 
2198 
2199 static
2200 cmsUInt8Number* Pack1Byte(CMSREGISTER _cmsTRANSFORM* info,
2201                           CMSREGISTER cmsUInt16Number wOut[],
2202                           CMSREGISTER cmsUInt8Number* output,
2203                           CMSREGISTER cmsUInt32Number Stride)
2204 {
2205     *output++ = FROM_16_TO_8(wOut[0]);
2206 
2207     return output;
2208 
2209     cmsUNUSED_PARAMETER(info);
2210     cmsUNUSED_PARAMETER(Stride);
2211 }
2212 
2213 
2214 static
2215 cmsUInt8Number* Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
2216                                   CMSREGISTER cmsUInt16Number wOut[],
2217                                   CMSREGISTER cmsUInt8Number* output,
2218                                   CMSREGISTER cmsUInt32Number Stride)
2219 {
2220     *output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
2221 
2222     return output;
2223 
2224     cmsUNUSED_PARAMETER(info);
2225     cmsUNUSED_PARAMETER(Stride);
2226 }
2227 
2228 
2229 static
2230 cmsUInt8Number* Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
2231                                CMSREGISTER cmsUInt16Number wOut[],
2232                                CMSREGISTER cmsUInt8Number* output,
2233                                CMSREGISTER cmsUInt32Number Stride)
2234 {
2235     *output++ = FROM_16_TO_8(wOut[0]);
2236     output++;
2237 
2238     return output;
2239 
2240     cmsUNUSED_PARAMETER(info);
2241     cmsUNUSED_PARAMETER(Stride);
2242 }
2243 
2244 
2245 static
2246 cmsUInt8Number* Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2247                                         CMSREGISTER cmsUInt16Number wOut[],
2248                                         CMSREGISTER cmsUInt8Number* output,
2249                                         CMSREGISTER cmsUInt32Number Stride)
2250 {
2251     output++;
2252     *output++ = FROM_16_TO_8(wOut[0]);
2253 
2254     return output;
2255 
2256     cmsUNUSED_PARAMETER(info);
2257     cmsUNUSED_PARAMETER(Stride);
2258 }
2259 
2260 static
2261 cmsUInt8Number* Pack1Word(CMSREGISTER _cmsTRANSFORM* info,
2262                           CMSREGISTER cmsUInt16Number wOut[],
2263                           CMSREGISTER cmsUInt8Number* output,
2264                           CMSREGISTER cmsUInt32Number Stride)
2265 {
2266     *(cmsUInt16Number*) output = wOut[0];
2267     output+= 2;
2268 
2269     return output;
2270 
2271     cmsUNUSED_PARAMETER(info);
2272     cmsUNUSED_PARAMETER(Stride);
2273 }
2274 
2275 
2276 static
2277 cmsUInt8Number* Pack1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
2278                                   CMSREGISTER cmsUInt16Number wOut[],
2279                                   CMSREGISTER cmsUInt8Number* output,
2280                                   CMSREGISTER cmsUInt32Number Stride)
2281 {
2282     *(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
2283     output+= 2;
2284 
2285     return output;
2286 
2287     cmsUNUSED_PARAMETER(info);
2288     cmsUNUSED_PARAMETER(Stride);
2289 }
2290 
2291 static
2292 cmsUInt8Number* Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM* info,
2293                                    CMSREGISTER cmsUInt16Number wOut[],
2294                                    CMSREGISTER cmsUInt8Number* output,
2295                                    CMSREGISTER cmsUInt32Number Stride)
2296 {
2297     *(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
2298     output+= 2;
2299 
2300     return output;
2301 
2302     cmsUNUSED_PARAMETER(info);
2303     cmsUNUSED_PARAMETER(Stride);
2304 }
2305 
2306 
2307 static
2308 cmsUInt8Number* Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM* info,
2309                                CMSREGISTER cmsUInt16Number wOut[],
2310                                CMSREGISTER cmsUInt8Number* output,
2311                                CMSREGISTER cmsUInt32Number Stride)
2312 {
2313     *(cmsUInt16Number*) output = wOut[0];
2314     output+= 4;
2315 
2316     return output;
2317 
2318     cmsUNUSED_PARAMETER(info);
2319     cmsUNUSED_PARAMETER(Stride);
2320 }
2321 
2322 static
2323 cmsUInt8Number* Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
2324                                         CMSREGISTER cmsUInt16Number wOut[],
2325                                         CMSREGISTER cmsUInt8Number* output,
2326                                         CMSREGISTER cmsUInt32Number Stride)
2327 {
2328     output += 2;
2329     *(cmsUInt16Number*) output = wOut[0];
2330     output+= 2;
2331 
2332     return output;
2333 
2334     cmsUNUSED_PARAMETER(info);
2335     cmsUNUSED_PARAMETER(Stride);
2336 }
2337 
2338 
2339 // Unencoded Float values -- don't try optimize speed
2340 static
2341 cmsUInt8Number* PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
2342                                     CMSREGISTER cmsUInt16Number wOut[],
2343                                     CMSREGISTER cmsUInt8Number* output,
2344                                     CMSREGISTER cmsUInt32Number Stride)
2345 {
2346 
2347     if (T_PLANAR(info -> OutputFormat)) {
2348 
2349         cmsCIELab  Lab;
2350         cmsFloat64Number* Out = (cmsFloat64Number*) output;
2351         cmsLabEncoded2Float(&Lab, wOut);
2352 
2353         Out[0]        = Lab.L;
2354         Out[Stride]   = Lab.a;
2355         Out[Stride*2] = Lab.b;
2356 
2357         return output + sizeof(cmsFloat64Number);
2358     }
2359     else {
2360 
2361         cmsLabEncoded2Float((cmsCIELab*) output, wOut);
2362         return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
2363     }
2364 }
2365 
2366 
2367 static
2368 cmsUInt8Number* PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
2369                                     CMSREGISTER cmsUInt16Number wOut[],
2370                                     CMSREGISTER cmsUInt8Number* output,
2371                                     CMSREGISTER cmsUInt32Number Stride)
2372 {
2373     cmsCIELab  Lab;
2374     cmsLabEncoded2Float(&Lab, wOut);
2375 
2376     if (T_PLANAR(info -> OutputFormat)) {
2377 
2378         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2379 
2380         Stride /= PixelSize(info->OutputFormat);
2381 
2382         Out[0]        = (cmsFloat32Number)Lab.L;
2383         Out[Stride]   = (cmsFloat32Number)Lab.a;
2384         Out[Stride*2] = (cmsFloat32Number)Lab.b;
2385 
2386         return output + sizeof(cmsFloat32Number);
2387     }
2388     else {
2389 
2390        ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
2391        ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
2392        ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
2393 
2394         return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
2395     }
2396 }
2397 
2398 static
2399 cmsUInt8Number* PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM* Info,
2400                                     CMSREGISTER cmsUInt16Number wOut[],
2401                                     CMSREGISTER cmsUInt8Number* output,
2402                                     CMSREGISTER cmsUInt32Number Stride)
2403 {
2404     if (T_PLANAR(Info -> OutputFormat)) {
2405 
2406         cmsCIEXYZ XYZ;
2407         cmsFloat64Number* Out = (cmsFloat64Number*) output;
2408         cmsXYZEncoded2Float(&XYZ, wOut);
2409 
2410         Stride /= PixelSize(Info->OutputFormat);
2411 
2412         Out[0]        = XYZ.X;
2413         Out[Stride]   = XYZ.Y;
2414         Out[Stride*2] = XYZ.Z;
2415 
2416         return output + sizeof(cmsFloat64Number);
2417 
2418     }
2419     else {
2420 
2421         cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
2422 
2423         return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2424     }
2425 }
2426 
2427 static
2428 cmsUInt8Number* PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM* Info,
2429                                    CMSREGISTER cmsUInt16Number wOut[],
2430                                    CMSREGISTER cmsUInt8Number* output,
2431                                    CMSREGISTER cmsUInt32Number Stride)
2432 {
2433     if (T_PLANAR(Info -> OutputFormat)) {
2434 
2435         cmsCIEXYZ XYZ;
2436         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2437         cmsXYZEncoded2Float(&XYZ, wOut);
2438 
2439         Stride /= PixelSize(Info->OutputFormat);
2440 
2441         Out[0]        = (cmsFloat32Number) XYZ.X;
2442         Out[Stride]   = (cmsFloat32Number) XYZ.Y;
2443         Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
2444 
2445         return output + sizeof(cmsFloat32Number);
2446 
2447     }
2448     else {
2449 
2450         cmsCIEXYZ XYZ;
2451         cmsFloat32Number* Out = (cmsFloat32Number*) output;
2452         cmsXYZEncoded2Float(&XYZ, wOut);
2453 
2454         Out[0] = (cmsFloat32Number) XYZ.X;
2455         Out[1] = (cmsFloat32Number) XYZ.Y;
2456         Out[2] = (cmsFloat32Number) XYZ.Z;
2457 
2458         return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
2459     }
2460 }
2461 
2462 static
2463 cmsUInt8Number* PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
2464                                 CMSREGISTER cmsUInt16Number wOut[],
2465                                 CMSREGISTER cmsUInt8Number* output,
2466                                 CMSREGISTER cmsUInt32Number Stride)
2467 {
2468     cmsUInt32Number nChan      = T_CHANNELS(info -> OutputFormat);
2469     cmsUInt32Number DoSwap     = T_DOSWAP(info ->OutputFormat);
2470     cmsUInt32Number Reverse    = T_FLAVOR(info ->OutputFormat);
2471     cmsUInt32Number Extra      = T_EXTRA(info -> OutputFormat);
2472     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> OutputFormat);
2473     cmsUInt32Number Planar     = T_PLANAR(info -> OutputFormat);
2474     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2475     cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
2476     cmsFloat64Number v = 0;
2477     cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
2478     cmsUInt32Number i, start = 0;
2479 
2480     Stride /= PixelSize(info->OutputFormat);
2481 
2482     if (ExtraFirst)
2483         start = Extra;
2484 
2485     for (i=0; i < nChan; i++) {
2486 


2496         else
2497             ((cmsFloat64Number*) output)[i + start] = v;
2498     }
2499 
2500 
2501     if (Extra == 0 && SwapFirst) {
2502 
2503          memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
2504         *swap1 = v;
2505     }
2506 
2507     if (T_PLANAR(info -> OutputFormat))
2508         return output + sizeof(cmsFloat64Number);
2509     else
2510         return output + (nChan + Extra) * sizeof(cmsFloat64Number);
2511 
2512 }
2513 
2514 
2515 static
2516 cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
2517                                 CMSREGISTER cmsUInt16Number wOut[],
2518                                 CMSREGISTER cmsUInt8Number* output,
2519                                 CMSREGISTER cmsUInt32Number Stride)
2520 {
2521        cmsUInt32Number nChan      = T_CHANNELS(info->OutputFormat);
2522        cmsUInt32Number DoSwap     = T_DOSWAP(info->OutputFormat);
2523        cmsUInt32Number Reverse    = T_FLAVOR(info->OutputFormat);
2524        cmsUInt32Number Extra      = T_EXTRA(info->OutputFormat);
2525        cmsUInt32Number SwapFirst  = T_SWAPFIRST(info->OutputFormat);
2526        cmsUInt32Number Planar     = T_PLANAR(info->OutputFormat);
2527        cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2528        cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
2529        cmsFloat64Number v = 0;
2530        cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
2531        cmsUInt32Number i, start = 0;
2532 
2533        Stride /= PixelSize(info->OutputFormat);
2534 
2535        if (ExtraFirst)
2536               start = Extra;
2537 
2538        for (i = 0; i < nChan; i++) {
2539 


2785     }
2786     else {
2787 
2788         Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
2789         Out[1] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
2790         Out[2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
2791 
2792         return output + (sizeof(cmsFloat64Number)*3 + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
2793     }
2794 
2795 }
2796 
2797 
2798 // ----------------------------------------------------------------------------------------------------------------
2799 
2800 #ifndef CMS_NO_HALF_SUPPORT
2801 
2802 // Decodes an stream of half floats to wIn[] described by input format
2803 
2804 static
2805 cmsUInt8Number* UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM* info,
2806                                 CMSREGISTER cmsUInt16Number wIn[],
2807                                 CMSREGISTER cmsUInt8Number* accum,
2808                                 CMSREGISTER cmsUInt32Number Stride)
2809 {
2810 
2811     cmsUInt32Number nChan      = T_CHANNELS(info -> InputFormat);
2812     cmsUInt32Number DoSwap     = T_DOSWAP(info ->InputFormat);
2813     cmsUInt32Number Reverse    = T_FLAVOR(info ->InputFormat);
2814     cmsUInt32Number SwapFirst  = T_SWAPFIRST(info -> InputFormat);
2815     cmsUInt32Number Extra      = T_EXTRA(info -> InputFormat);
2816     cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2817     cmsUInt32Number Planar     = T_PLANAR(info -> InputFormat);
2818     cmsFloat32Number v;
2819     cmsUInt32Number i, start = 0;
2820     cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
2821 
2822 
2823     Stride /= PixelSize(info->OutputFormat);
2824 
2825     if (ExtraFirst)
2826             start = Extra;
2827 
2828     for (i=0; i < nChan; i++) {


2891 
2892         wIn[index] = Reverse ? 1 - v : v;
2893     }
2894 
2895 
2896     if (Extra == 0 && SwapFirst) {
2897         cmsFloat32Number tmp = wIn[0];
2898 
2899         memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
2900         wIn[nChan-1] = tmp;
2901     }
2902 
2903     if (T_PLANAR(info -> InputFormat))
2904         return accum + sizeof(cmsUInt16Number);
2905     else
2906         return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
2907 }
2908 
2909 
2910 static
2911 cmsUInt8Number* PackHalfFrom16(CMSREGISTER _cmsTRANSFORM* info,
2912                                 CMSREGISTER cmsUInt16Number wOut[],
2913                                 CMSREGISTER cmsUInt8Number* output,
2914                                 CMSREGISTER cmsUInt32Number Stride)
2915 {
2916        cmsUInt32Number nChan      = T_CHANNELS(info->OutputFormat);
2917        cmsUInt32Number DoSwap     = T_DOSWAP(info->OutputFormat);
2918        cmsUInt32Number Reverse    = T_FLAVOR(info->OutputFormat);
2919        cmsUInt32Number Extra      = T_EXTRA(info->OutputFormat);
2920        cmsUInt32Number SwapFirst  = T_SWAPFIRST(info->OutputFormat);
2921        cmsUInt32Number Planar     = T_PLANAR(info->OutputFormat);
2922        cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
2923        cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F;
2924        cmsFloat32Number v = 0;
2925        cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
2926        cmsUInt32Number i, start = 0;
2927 
2928        Stride /= PixelSize(info->OutputFormat);
2929 
2930        if (ExtraFirst)
2931               start = Extra;
2932 
2933        for (i = 0; i < nChan; i++) {
2934 


< prev index next >