1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.hardware; 17 18 import android.annotation.IntDef; 19 20 import java.lang.annotation.Retention; 21 import java.lang.annotation.RetentionPolicy; 22 23 /** 24 * DataSpace identifies three components of colors - standard (primaries), transfer and range. 25 * 26 * <p>A DataSpace describes how buffer data, such as from an {@link android.media.Image Image} 27 * or a {@link android.hardware.HardwareBuffer HardwareBuffer} 28 * should be interpreted by both applications and typical hardware.</p> 29 * 30 * <p>As buffer information is not guaranteed to be representative of color information, 31 * while DataSpace is typically used to describe three aspects of interpreting colors, 32 * some DataSpaces may describe other typical interpretations of buffer data 33 * such as depth information.</p> 34 * 35 * <p>Note that while {@link android.graphics.ColorSpace ColorSpace} and {@code DataSpace} 36 * are similar concepts, they are not equivalent. Not all ColorSpaces, 37 * such as {@link android.graphics.ColorSpace.Named#ACES ColorSpace.Named.ACES}, 38 * are able to be understood by typical hardware blocks so they cannot be DataSpaces.</p> 39 * 40 * <h3>Standard aspect</h3> 41 * 42 * <p>Defines the chromaticity coordinates of the source primaries in terms of 43 * the CIE 1931 definition of x and y specified in ISO 11664-1.</p> 44 * 45 * <h3>Transfer aspect</h3> 46 * 47 * <p>Transfer characteristics are the opto-electronic transfer characteristic 48 * at the source as a function of linear optical intensity (luminance).</p> 49 * 50 * <p>For digital signals, E corresponds to the recorded value. Normally, the 51 * transfer function is applied in RGB space to each of the R, G and B 52 * components independently. This may result in color shift that can be 53 * minized by applying the transfer function in Lab space only for the L 54 * component. Implementation may apply the transfer function in RGB space 55 * for all pixel formats if desired.</p> 56 * 57 * <h3>Range aspect</h3> 58 * 59 * <p>Defines the range of values corresponding to the unit range of {@code 0-1}.</p> 60 */ 61 62 public final class DataSpace { 63 /** @hide */ 64 @Retention(RetentionPolicy.SOURCE) 65 @IntDef(flag = true, value = { 66 STANDARD_UNSPECIFIED, 67 STANDARD_BT709, 68 STANDARD_BT601_625, 69 STANDARD_BT601_625_UNADJUSTED, 70 STANDARD_BT601_525, 71 STANDARD_BT601_525_UNADJUSTED, 72 STANDARD_BT2020, 73 STANDARD_BT2020_CONSTANT_LUMINANCE, 74 STANDARD_BT470M, 75 STANDARD_FILM, 76 STANDARD_DCI_P3, 77 STANDARD_ADOBE_RGB 78 }) 79 public @interface DataSpaceStandard {}; 80 81 private static final int STANDARD_MASK = 63 << 16; 82 83 /** 84 * Chromacity coordinates are unknown or are determined by the application. 85 */ 86 public static final int STANDARD_UNSPECIFIED = 0 << 16; 87 /** 88 * Use the unadjusted {@code KR = 0.2126}, {@code KB = 0.0722} luminance interpretation 89 * for RGB conversion. 90 * 91 * <pre> 92 * Primaries: x y 93 * green 0.300 0.600 94 * blue 0.150 0.060 95 * red 0.640 0.330 96 * white (D65) 0.3127 0.3290 </pre> 97 */ 98 public static final int STANDARD_BT709 = 1 << 16; 99 /** 100 * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation 101 * for RGB conversion from the one purely determined by the primaries 102 * to minimize the color shift into RGB space that uses BT.709 103 * primaries. 104 * 105 * <pre> 106 * Primaries: x y 107 * green 0.290 0.600 108 * blue 0.150 0.060 109 * red 0.640 0.330 110 * white (D65) 0.3127 0.3290 </pre> 111 */ 112 public static final int STANDARD_BT601_625 = 2 << 16; 113 /** 114 * Use the unadjusted {@code KR = 0.222}, {@code KB = 0.071} luminance interpretation 115 * for RGB conversion. 116 * 117 * <pre> 118 * Primaries: x y 119 * green 0.290 0.600 120 * blue 0.150 0.060 121 * red 0.640 0.330 122 * white (D65) 0.3127 0.3290 </pre> 123 */ 124 public static final int STANDARD_BT601_625_UNADJUSTED = 3 << 16; 125 /** 126 * Use the adjusted {@code KR = 0.299}, {@code KB = 0.114} luminance interpretation 127 * for RGB conversion from the one purely determined by the primaries 128 * to minimize the color shift into RGB space that uses BT.709 129 * primaries. 130 * 131 * <pre> 132 * Primaries: x y 133 * green 0.310 0.595 134 * blue 0.155 0.070 135 * red 0.630 0.340 136 * white (D65) 0.3127 0.3290 </pre> 137 */ 138 public static final int STANDARD_BT601_525 = 4 << 16; 139 /** 140 * Use the unadjusted {@code KR = 0.212}, {@code KB = 0.087} luminance interpretation 141 * for RGB conversion (as in SMPTE 240M). 142 * 143 * <pre> 144 * Primaries: x y 145 * green 0.310 0.595 146 * blue 0.155 0.070 147 * red 0.630 0.340 148 * white (D65) 0.3127 0.3290 </pre> 149 */ 150 public static final int STANDARD_BT601_525_UNADJUSTED = 5 << 16; 151 /** 152 * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation 153 * for RGB conversion. 154 * 155 * <pre> 156 * Primaries: x y 157 * green 0.170 0.797 158 * blue 0.131 0.046 159 * red 0.708 0.292 160 * white (D65) 0.3127 0.3290 </pre> 161 */ 162 public static final int STANDARD_BT2020 = 6 << 16; 163 /** 164 * Use the unadjusted {@code KR = 0.2627}, {@code KB = 0.0593} luminance interpretation 165 * for RGB conversion using the linear domain. 166 * 167 * <pre> 168 * Primaries: x y 169 * green 0.170 0.797 170 * blue 0.131 0.046 171 * red 0.708 0.292 172 * white (D65) 0.3127 0.3290 </pre> 173 */ 174 public static final int STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16; 175 /** 176 * Use the unadjusted {@code KR = 0.30}, {@code KB = 0.11} luminance interpretation 177 * for RGB conversion. 178 * 179 * <pre> 180 * Primaries: x y 181 * green 0.21 0.71 182 * blue 0.14 0.08 183 * red 0.67 0.33 184 * white (C) 0.310 0.316 </pre> 185 */ 186 public static final int STANDARD_BT470M = 8 << 16; 187 /** 188 * Use the unadjusted {@code KR = 0.254}, {@code KB = 0.068} luminance interpretation 189 * for RGB conversion. 190 * 191 * <pre> 192 * Primaries: x y 193 * green 0.243 0.692 194 * blue 0.145 0.049 195 * red 0.681 0.319 196 * white (C) 0.310 0.316 </pre> 197 */ 198 public static final int STANDARD_FILM = 9 << 16; 199 /** 200 * SMPTE EG 432-1 and SMPTE RP 431-2. 201 * 202 * <pre> 203 * Primaries: x y 204 * green 0.265 0.690 205 * blue 0.150 0.060 206 * red 0.680 0.320 207 * white (D65) 0.3127 0.3290 </pre> 208 */ 209 public static final int STANDARD_DCI_P3 = 10 << 16; 210 /** 211 * Adobe RGB primaries. 212 * 213 * <pre> 214 * Primaries: x y 215 * green 0.210 0.710 216 * blue 0.150 0.060 217 * red 0.640 0.330 218 * white (D65) 0.3127 0.3290 </pre> 219 */ 220 public static final int STANDARD_ADOBE_RGB = 11 << 16; 221 222 /** @hide */ 223 @Retention(RetentionPolicy.SOURCE) 224 @IntDef(flag = true, value = { 225 TRANSFER_UNSPECIFIED, 226 TRANSFER_LINEAR, 227 TRANSFER_SRGB, 228 TRANSFER_SMPTE_170M, 229 TRANSFER_GAMMA2_2, 230 TRANSFER_GAMMA2_6, 231 TRANSFER_GAMMA2_8, 232 TRANSFER_ST2084, 233 TRANSFER_HLG 234 }) 235 public @interface DataSpaceTransfer {}; 236 237 private static final int TRANSFER_MASK = 31 << 22; 238 239 /** 240 * Transfer characteristics are unknown or are determined by the 241 * application. 242 */ 243 public static final int TRANSFER_UNSPECIFIED = 0 << 22; 244 /** 245 * Linear transfer. 246 * 247 * <pre>{@code 248 * Transfer characteristic curve: 249 * E = L 250 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 251 * E - corresponding electrical signal}</pre> 252 */ 253 public static final int TRANSFER_LINEAR = 1 << 22; 254 /** 255 * sRGB transfer. 256 * 257 * <pre>{@code 258 * Transfer characteristic curve: 259 * E = 1.055 * L^(1/2.4) - 0.055 for 0.0031308 <= L <= 1 260 * = 12.92 * L for 0 <= L < 0.0031308 261 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 262 * E - corresponding electrical signal}</pre> 263 * 264 * Use for RGB formats. 265 */ 266 public static final int TRANSFER_SRGB = 2 << 22; 267 /** 268 * SMPTE 170M transfer. 269 * 270 * <pre>{@code 271 * Transfer characteristic curve: 272 * E = 1.099 * L ^ 0.45 - 0.099 for 0.018 <= L <= 1 273 * = 4.500 * L for 0 <= L < 0.018 274 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 275 * E - corresponding electrical signal}</pre> 276 * 277 * Use for YCbCr formats. 278 */ 279 public static final int TRANSFER_SMPTE_170M = 3 << 22; 280 /** 281 * Display gamma 2.2. 282 * 283 * <pre>{@code 284 * Transfer characteristic curve: 285 * E = L ^ (1/2.2) 286 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 287 * E - corresponding electrical signal}</pre> 288 */ 289 public static final int TRANSFER_GAMMA2_2 = 4 << 22; 290 /** 291 * Display gamma 2.6. 292 * 293 * <pre>{@code 294 * Transfer characteristic curve: 295 * E = L ^ (1/2.6) 296 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 297 * E - corresponding electrical signal}</pre> 298 */ 299 public static final int TRANSFER_GAMMA2_6 = 5 << 22; 300 /** 301 * Display gamma 2.8. 302 * 303 * <pre>{@code 304 * Transfer characteristic curve: 305 * E = L ^ (1/2.8) 306 * L - luminance of image 0 <= L <= 1 for conventional colorimetry 307 * E - corresponding electrical signal}</pre> 308 */ 309 public static final int TRANSFER_GAMMA2_8 = 6 << 22; 310 /** 311 * SMPTE ST 2084 (Dolby Perceptual Quantizer). 312 * 313 * <pre>{@code 314 * Transfer characteristic curve: 315 * E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m 316 * c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375 317 * c2 = 32 * 2413 / 4096 = 18.8515625 318 * c3 = 32 * 2392 / 4096 = 18.6875 319 * m = 128 * 2523 / 4096 = 78.84375 320 * n = 0.25 * 2610 / 4096 = 0.1593017578125 321 * L - luminance of image 0 <= L <= 1 for HDR colorimetry. 322 * L = 1 corresponds to 10000 cd/m2 323 * E - corresponding electrical signal}</pre> 324 */ 325 public static final int TRANSFER_ST2084 = 7 << 22; 326 /** 327 * ARIB STD-B67 Hybrid Log Gamma. 328 * 329 * <pre>{@code 330 * Transfer characteristic curve: 331 * E = r * L^0.5 for 0 <= L <= 1 332 * = a * ln(L - b) + c for 1 < L 333 * a = 0.17883277 334 * b = 0.28466892 335 * c = 0.55991073 336 * r = 0.5 337 * L - luminance of image 0 <= L for HDR colorimetry. L = 1 corresponds 338 * to reference white level of 100 cd/m2 339 * E - corresponding electrical signal}</pre> 340 */ 341 public static final int TRANSFER_HLG = 8 << 22; 342 343 /** @hide */ 344 @Retention(RetentionPolicy.SOURCE) 345 @IntDef(flag = true, value = { 346 RANGE_UNSPECIFIED, 347 RANGE_FULL, 348 RANGE_LIMITED, 349 RANGE_EXTENDED 350 }) 351 public @interface DataSpaceRange {}; 352 353 private static final int RANGE_MASK = 7 << 27; 354 355 /** 356 * Range characteristics are unknown or are determined by the application. 357 */ 358 public static final int RANGE_UNSPECIFIED = 0 << 27; 359 /** 360 * Full range uses all values for Y, Cb and Cr from 361 * {@code 0} to {@code 2^b-1}, where b is the bit depth of the color format. 362 */ 363 public static final int RANGE_FULL = 1 << 27; 364 /** 365 * Limited range uses values {@code 16/256*2^b} to {@code 235/256*2^b} for Y, and 366 * {@code 1/16*2^b} to {@code 15/16*2^b} for Cb, Cr, R, G and B, where b is the bit depth of 367 * the color format. 368 * 369 * <p>E.g. For 8-bit-depth formats: 370 * Luma (Y) samples should range from 16 to 235, inclusive 371 * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive 372 * 373 * For 10-bit-depth formats: 374 * Luma (Y) samples should range from 64 to 940, inclusive 375 * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive. </p> 376 */ 377 public static final int RANGE_LIMITED = 2 << 27; 378 /** 379 * Extended range is used for scRGB only. 380 * 381 * <p>Intended for use with floating point pixel formats. [0.0 - 1.0] is the standard 382 * sRGB space. Values outside the range [0.0 - 1.0] can encode 383 * color outside the sRGB gamut. [-0.5, 7.5] is the scRGB range. 384 * Used to blend/merge multiple dataspaces on a single display.</p> 385 */ 386 public static final int RANGE_EXTENDED = 3 << 27; 387 388 /** @hide */ 389 @Retention(RetentionPolicy.SOURCE) 390 @IntDef(flag = true, value = { 391 DATASPACE_UNKNOWN, 392 DATASPACE_SCRGB_LINEAR, 393 DATASPACE_SRGB, 394 DATASPACE_SCRGB, 395 DATASPACE_DISPLAY_P3, 396 DATASPACE_BT2020_PQ, 397 DATASPACE_ADOBE_RGB, 398 DATASPACE_JFIF, 399 DATASPACE_BT601_625, 400 DATASPACE_BT601_525, 401 DATASPACE_BT2020, 402 DATASPACE_BT709, 403 DATASPACE_DCI_P3, 404 DATASPACE_SRGB_LINEAR 405 }) 406 public @interface NamedDataSpace {}; 407 408 /** 409 * Default-assumption data space, when not explicitly specified. 410 * 411 * <p>It is safest to assume a buffer is an image with sRGB primaries and 412 * encoding ranges, but the consumer and/or the producer of the data may 413 * simply be using defaults. No automatic gamma transform should be 414 * expected, except for a possible display gamma transform when drawn to a 415 * screen.</p> 416 */ 417 public static final int DATASPACE_UNKNOWN = 0; 418 /** 419 * scRGB linear encoding. 420 * 421 * <p>Composed of the following -</p> 422 * <pre> 423 * Primaries: STANDARD_BT709 424 * Transfer: TRANSFER_LINEAR 425 * Range: RANGE_EXTENDED</pre> 426 * 427 * The values are floating point. 428 * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits. 429 * Values beyond the range [0.0 - 1.0] would correspond to other colors 430 * spaces and/or HDR content. 431 */ 432 public static final int DATASPACE_SCRGB_LINEAR = 406913024; 433 /** 434 * sRGB gamma encoding. 435 * 436 * <p>Composed of the following -</p> 437 * <pre> 438 * Primaries: STANDARD_BT709 439 * Transfer: TRANSFER_SRGB 440 * Range: RANGE_FULL</pre> 441 * 442 * When written, the inverse transformation is performed. 443 * 444 * The alpha component, if present, is always stored in linear space and 445 * is left unmodified when read or written. 446 */ 447 public static final int DATASPACE_SRGB = 142671872; 448 /** 449 * scRGB gamma encoding. 450 * 451 * <p>Composed of the following -</p> 452 * <pre> 453 * Primaries: STANDARD_BT709 454 * Transfer: TRANSFER_SRGB 455 * Range: RANGE_EXTENDED</pre> 456 * 457 * The values are floating point. 458 * 459 * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits. 460 * Values beyond the range [0.0 - 1.0] would correspond to other colors 461 * spaces and/or HDR content. 462 */ 463 public static final int DATASPACE_SCRGB = 411107328; 464 /** 465 * Display P3 encoding. 466 * 467 * <p>Composed of the following -</p> 468 * <pre> 469 * Primaries: STANDARD_DCI_P3 470 * Transfer: TRANSFER_SRGB 471 * Range: RANGE_FULL</pre> 472 */ 473 public static final int DATASPACE_DISPLAY_P3 = 143261696; 474 /** 475 * ITU-R Recommendation 2020 (BT.2020) 476 * 477 * Ultra High-definition television. 478 * 479 * <p>Composed of the following -</p> 480 * <pre> 481 * Primaries: STANDARD_BT2020 482 * Transfer: TRANSFER_ST2084 483 * Range: RANGE_FULL</pre> 484 */ 485 public static final int DATASPACE_BT2020_PQ = 163971072; 486 /** 487 * Adobe RGB encoding. 488 * 489 * <p>Composed of the following -</p> 490 * <pre> 491 * Primaries: STANDARD_ADOBE_RGB 492 * Transfer: TRANSFER_GAMMA2_2 493 * Range: RANGE_FULL</pre> 494 * 495 * Note: Application is responsible for gamma encoding the data. 496 */ 497 public static final int DATASPACE_ADOBE_RGB = 151715840; 498 /** 499 * JPEG File Interchange Format (JFIF). 500 * 501 * <p>Composed of the following -</p> 502 * <pre> 503 * Primaries: STANDARD_BT601_625 504 * Transfer: TRANSFER_SMPTE_170M 505 * Range: RANGE_FULL</pre> 506 * 507 * Same model as BT.601-625, but all values (Y, Cb, Cr) range from {@code 0} to {@code 255} 508 */ 509 public static final int DATASPACE_JFIF = 146931712; 510 /** 511 * ITU-R Recommendation 601 (BT.601) - 525-line 512 * 513 * Standard-definition television, 525 Lines (NTSC). 514 * 515 * <p>Composed of the following -</p> 516 * <pre> 517 * Primaries: STANDARD_BT601_625 518 * Transfer: TRANSFER_SMPTE_170M 519 * Range: RANGE_LIMITED</pre> 520 */ 521 public static final int DATASPACE_BT601_625 = 281149440; 522 /** 523 * ITU-R Recommendation 709 (BT.709) 524 * 525 * High-definition television. 526 * 527 * <p>Composed of the following -</p> 528 * <pre> 529 * Primaries: STANDARD_BT601_525 530 * Transfer: TRANSFER_SMPTE_170M 531 * Range: RANGE_LIMITED</pre> 532 */ 533 public static final int DATASPACE_BT601_525 = 281280512; 534 /** 535 * ITU-R Recommendation 2020 (BT.2020) 536 * 537 * Ultra High-definition television. 538 * 539 * <p>Composed of the following -</p> 540 * <pre> 541 * Primaries: STANDARD_BT2020 542 * Transfer: TRANSFER_SMPTE_170M 543 * Range: RANGE_FULL</pre> 544 */ 545 public static final int DATASPACE_BT2020 = 147193856; 546 /** 547 * ITU-R Recommendation 709 (BT.709) 548 * 549 * High-definition television. 550 * 551 * <p>Composed of the following -</p> 552 * <pre> 553 * Primaries: STANDARD_BT709 554 * Transfer: TRANSFER_SMPTE_170M 555 * Range: RANGE_LIMITED</pre> 556 */ 557 public static final int DATASPACE_BT709 = 281083904; 558 /** 559 * SMPTE EG 432-1 and SMPTE RP 431-2 560 * 561 * Digital Cinema DCI-P3. 562 * 563 * <p>Composed of the following -</p> 564 * <pre> 565 * Primaries: STANDARD_DCI_P3 566 * Transfer: TRANSFER_GAMMA2_6 567 * Range: RANGE_FULL</pre> 568 * 569 * Note: Application is responsible for gamma encoding the data as 570 * a 2.6 gamma encoding is not supported in HW. 571 */ 572 public static final int DATASPACE_DCI_P3 = 155844608; 573 /** 574 * sRGB linear encoding. 575 * 576 * <p>Composed of the following -</p> 577 * <pre> 578 * Primaries: STANDARD_BT709 579 * Transfer: TRANSFER_LINEAR 580 * Range: RANGE_FULL</pre> 581 * 582 * The values are encoded using the full range ([0,255] for 8-bit) for all 583 * components. 584 */ 585 public static final int DATASPACE_SRGB_LINEAR = 138477568; 586 DataSpace()587 private DataSpace() {} 588 589 /** 590 * Pack the dataSpace value using standard, transfer and range field value. 591 * Field values should be in the correct bits place. 592 * 593 * @param standard Chromaticity coordinates of source primaries 594 * @param transfer Opto-electronic transfer characteristic at the source 595 * @param range The range of values 596 * 597 * @return The int dataspace packed by standard, transfer and range value 598 */ pack(@ataSpaceStandard int standard, @DataSpaceTransfer int transfer, @DataSpaceRange int range)599 public static @NamedDataSpace int pack(@DataSpaceStandard int standard, 600 @DataSpaceTransfer int transfer, 601 @DataSpaceRange int range) { 602 if ((standard & STANDARD_MASK) != standard) { 603 throw new IllegalArgumentException("Invalid standard " + standard); 604 } 605 if ((transfer & TRANSFER_MASK) != transfer) { 606 throw new IllegalArgumentException("Invalid transfer " + transfer); 607 } 608 if ((range & RANGE_MASK) != range) { 609 throw new IllegalArgumentException("Invalid range " + range); 610 } 611 return standard | transfer | range; 612 } 613 614 /** 615 * Unpack the standard field value from the packed dataSpace value. 616 * 617 * @param dataSpace The packed dataspace value 618 * 619 * @return The standard aspect 620 */ getStandard(@amedDataSpace int dataSpace)621 public static @DataSpaceStandard int getStandard(@NamedDataSpace int dataSpace) { 622 @DataSpaceStandard int standard = dataSpace & STANDARD_MASK; 623 return standard; 624 } 625 626 /** 627 * Unpack the transfer field value from the packed dataSpace value 628 * 629 * @param dataSpace The packed dataspace value 630 * 631 * @return The transfer aspect 632 */ getTransfer(@amedDataSpace int dataSpace)633 public static @DataSpaceTransfer int getTransfer(@NamedDataSpace int dataSpace) { 634 @DataSpaceTransfer int transfer = dataSpace & TRANSFER_MASK; 635 return transfer; 636 } 637 638 /** 639 * Unpack the range field value from the packed dataSpace value 640 * 641 * @param dataSpace The packed dataspace value 642 * 643 * @return The range aspect 644 */ getRange(@amedDataSpace int dataSpace)645 public static @DataSpaceRange int getRange(@NamedDataSpace int dataSpace) { 646 @DataSpaceRange int range = dataSpace & RANGE_MASK; 647 return range; 648 } 649 } 650