formats.c revision 4a49301e
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.7 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (c) 2008-2009 VMware, Inc. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27#include "imports.h" 28#include "formats.h" 29#include "config.h" 30 31 32/** 33 * Information about texture formats. 34 */ 35struct gl_format_info 36{ 37 gl_format Name; 38 39 /** text name for debugging */ 40 const char *StrName; 41 42 /** 43 * Base format is one of GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, 44 * GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, GL_COLOR_INDEX, 45 * GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. 46 */ 47 GLenum BaseFormat; 48 49 /** 50 * Logical data type: one of GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALED, 51 * GL_UNSIGNED_INT, GL_SIGNED_INT, GL_FLOAT. 52 */ 53 GLenum DataType; 54 55 GLubyte RedBits; 56 GLubyte GreenBits; 57 GLubyte BlueBits; 58 GLubyte AlphaBits; 59 GLubyte LuminanceBits; 60 GLubyte IntensityBits; 61 GLubyte IndexBits; 62 GLubyte DepthBits; 63 GLubyte StencilBits; 64 65 /** 66 * To describe compressed formats. If not compressed, Width=Height=1. 67 */ 68 GLubyte BlockWidth, BlockHeight; 69 GLubyte BytesPerBlock; 70}; 71 72 73/** 74 * Info about each format. 75 * These must be in the same order as the MESA_FORMAT_* enums so that 76 * we can do lookups without searching. 77 */ 78static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 79{ 80 { 81 MESA_FORMAT_NONE, /* Name */ 82 "MESA_FORMAT_NONE", /* StrName */ 83 GL_NONE, /* BaseFormat */ 84 GL_NONE, /* DataType */ 85 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 86 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 87 0, 0, 0 /* BlockWidth/Height,Bytes */ 88 }, 89 { 90 MESA_FORMAT_RGBA8888, /* Name */ 91 "MESA_FORMAT_RGBA8888", /* StrName */ 92 GL_RGBA, /* BaseFormat */ 93 GL_UNSIGNED_NORMALIZED, /* DataType */ 94 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ 95 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 96 1, 1, 4 /* BlockWidth/Height,Bytes */ 97 }, 98 { 99 MESA_FORMAT_RGBA8888_REV, /* Name */ 100 "MESA_FORMAT_RGBA8888_REV", /* StrName */ 101 GL_RGBA, /* BaseFormat */ 102 GL_UNSIGNED_NORMALIZED, /* DataType */ 103 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ 104 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 105 1, 1, 4 /* BlockWidth/Height,Bytes */ 106 }, 107 { 108 MESA_FORMAT_ARGB8888, /* Name */ 109 "MESA_FORMAT_ARGB8888", /* StrName */ 110 GL_RGBA, /* BaseFormat */ 111 GL_UNSIGNED_NORMALIZED, /* DataType */ 112 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ 113 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 114 1, 1, 4 /* BlockWidth/Height,Bytes */ 115 }, 116 { 117 MESA_FORMAT_ARGB8888_REV, /* Name */ 118 "MESA_FORMAT_ARGB8888_REV", /* StrName */ 119 GL_RGBA, /* BaseFormat */ 120 GL_UNSIGNED_NORMALIZED, /* DataType */ 121 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ 122 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 123 1, 1, 4 /* BlockWidth/Height,Bytes */ 124 }, 125 { 126 MESA_FORMAT_XRGB8888, /* Name */ 127 "MESA_FORMAT_XRGB8888", /* StrName */ 128 GL_RGB, /* BaseFormat */ 129 GL_UNSIGNED_NORMALIZED, /* DataType */ 130 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ 131 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 132 1, 1, 4 /* BlockWidth/Height,Bytes */ 133 }, 134 { 135 MESA_FORMAT_XRGB8888_REV, /* Name */ 136 "MESA_FORMAT_XRGB8888_REV", /* StrName */ 137 GL_RGB, /* BaseFormat */ 138 GL_UNSIGNED_NORMALIZED, /* DataType */ 139 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ 140 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 141 1, 1, 4 /* BlockWidth/Height,Bytes */ 142 }, 143 { 144 MESA_FORMAT_RGB888, /* Name */ 145 "MESA_FORMAT_RGB888", /* StrName */ 146 GL_RGB, /* BaseFormat */ 147 GL_UNSIGNED_NORMALIZED, /* DataType */ 148 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ 149 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 150 1, 1, 3 /* BlockWidth/Height,Bytes */ 151 }, 152 { 153 MESA_FORMAT_BGR888, /* Name */ 154 "MESA_FORMAT_BGR888", /* StrName */ 155 GL_RGB, /* BaseFormat */ 156 GL_UNSIGNED_NORMALIZED, /* DataType */ 157 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ 158 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 159 1, 1, 3 /* BlockWidth/Height,Bytes */ 160 }, 161 { 162 MESA_FORMAT_RGB565, /* Name */ 163 "MESA_FORMAT_RGB565", /* StrName */ 164 GL_RGB, /* BaseFormat */ 165 GL_UNSIGNED_NORMALIZED, /* DataType */ 166 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ 167 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 168 1, 1, 2 /* BlockWidth/Height,Bytes */ 169 }, 170 { 171 MESA_FORMAT_RGB565_REV, /* Name */ 172 "MESA_FORMAT_RGB565_REV", /* StrName */ 173 GL_RGB, /* BaseFormat */ 174 GL_UNSIGNED_NORMALIZED, /* DataType */ 175 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ 176 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 177 1, 1, 2 /* BlockWidth/Height,Bytes */ 178 }, 179 { 180 MESA_FORMAT_ARGB4444, /* Name */ 181 "MESA_FORMAT_ARGB4444", /* StrName */ 182 GL_RGBA, /* BaseFormat */ 183 GL_UNSIGNED_NORMALIZED, /* DataType */ 184 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ 185 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 186 1, 1, 2 /* BlockWidth/Height,Bytes */ 187 }, 188 { 189 MESA_FORMAT_ARGB4444_REV, /* Name */ 190 "MESA_FORMAT_ARGB4444_REV", /* StrName */ 191 GL_RGBA, /* BaseFormat */ 192 GL_UNSIGNED_NORMALIZED, /* DataType */ 193 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ 194 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 195 1, 1, 2 /* BlockWidth/Height,Bytes */ 196 }, 197 { 198 MESA_FORMAT_RGBA5551, /* Name */ 199 "MESA_FORMAT_RGBA5551", /* StrName */ 200 GL_RGBA, /* BaseFormat */ 201 GL_UNSIGNED_NORMALIZED, /* DataType */ 202 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ 203 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 204 1, 1, 2 /* BlockWidth/Height,Bytes */ 205 }, 206 { 207 MESA_FORMAT_ARGB1555, /* Name */ 208 "MESA_FORMAT_ARGB1555", /* StrName */ 209 GL_RGBA, /* BaseFormat */ 210 GL_UNSIGNED_NORMALIZED, /* DataType */ 211 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ 212 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 213 1, 1, 2 /* BlockWidth/Height,Bytes */ 214 }, 215 { 216 MESA_FORMAT_ARGB1555_REV, /* Name */ 217 "MESA_FORMAT_ARGB1555_REV", /* StrName */ 218 GL_RGBA, /* BaseFormat */ 219 GL_UNSIGNED_NORMALIZED, /* DataType */ 220 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ 221 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 222 1, 1, 2 /* BlockWidth/Height,Bytes */ 223 }, 224 { 225 MESA_FORMAT_AL88, /* Name */ 226 "MESA_FORMAT_AL88", /* StrName */ 227 GL_LUMINANCE_ALPHA, /* BaseFormat */ 228 GL_UNSIGNED_NORMALIZED, /* DataType */ 229 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ 230 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 231 1, 1, 2 /* BlockWidth/Height,Bytes */ 232 }, 233 { 234 MESA_FORMAT_AL88_REV, /* Name */ 235 "MESA_FORMAT_AL88_REV", /* StrName */ 236 GL_LUMINANCE_ALPHA, /* BaseFormat */ 237 GL_UNSIGNED_NORMALIZED, /* DataType */ 238 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ 239 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 240 1, 1, 2 /* BlockWidth/Height,Bytes */ 241 }, 242 { 243 MESA_FORMAT_AL1616, /* Name */ 244 "MESA_FORMAT_AL1616", /* StrName */ 245 GL_LUMINANCE_ALPHA, /* BaseFormat */ 246 GL_UNSIGNED_NORMALIZED, /* DataType */ 247 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ 248 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 249 1, 1, 4 /* BlockWidth/Height,Bytes */ 250 }, 251 { 252 MESA_FORMAT_AL1616_REV, /* Name */ 253 "MESA_FORMAT_AL1616_REV", /* StrName */ 254 GL_LUMINANCE_ALPHA, /* BaseFormat */ 255 GL_UNSIGNED_NORMALIZED, /* DataType */ 256 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ 257 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 258 1, 1, 4 /* BlockWidth/Height,Bytes */ 259 }, 260 { 261 MESA_FORMAT_RGB332, /* Name */ 262 "MESA_FORMAT_RGB332", /* StrName */ 263 GL_RGB, /* BaseFormat */ 264 GL_UNSIGNED_NORMALIZED, /* DataType */ 265 3, 3, 2, 0, /* Red/Green/Blue/AlphaBits */ 266 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 267 1, 1, 1 /* BlockWidth/Height,Bytes */ 268 }, 269 { 270 MESA_FORMAT_A8, /* Name */ 271 "MESA_FORMAT_A8", /* StrName */ 272 GL_ALPHA, /* BaseFormat */ 273 GL_UNSIGNED_NORMALIZED, /* DataType */ 274 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ 275 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 276 1, 1, 1 /* BlockWidth/Height,Bytes */ 277 }, 278 { 279 MESA_FORMAT_L8, /* Name */ 280 "MESA_FORMAT_L8", /* StrName */ 281 GL_LUMINANCE, /* BaseFormat */ 282 GL_UNSIGNED_NORMALIZED, /* DataType */ 283 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 284 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 285 1, 1, 1 /* BlockWidth/Height,Bytes */ 286 }, 287 { 288 MESA_FORMAT_I8, /* Name */ 289 "MESA_FORMAT_I8", /* StrName */ 290 GL_INTENSITY, /* BaseFormat */ 291 GL_UNSIGNED_NORMALIZED, /* DataType */ 292 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 293 0, 8, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 294 1, 1, 1 /* BlockWidth/Height,Bytes */ 295 }, 296 { 297 MESA_FORMAT_CI8, /* Name */ 298 "MESA_FORMAT_CI8", /* StrName */ 299 GL_COLOR_INDEX, /* BaseFormat */ 300 GL_UNSIGNED_INT, /* DataType */ 301 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 302 0, 0, 8, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 303 1, 1, 1 /* BlockWidth/Height,Bytes */ 304 }, 305 { 306 MESA_FORMAT_YCBCR, /* Name */ 307 "MESA_FORMAT_YCBCR", /* StrName */ 308 GL_YCBCR_MESA, /* BaseFormat */ 309 GL_UNSIGNED_NORMALIZED, /* DataType */ 310 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 311 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 312 1, 1, 2 /* BlockWidth/Height,Bytes */ 313 }, 314 { 315 MESA_FORMAT_YCBCR_REV, /* Name */ 316 "MESA_FORMAT_YCBCR_REV", /* StrName */ 317 GL_YCBCR_MESA, /* BaseFormat */ 318 GL_UNSIGNED_NORMALIZED, /* DataType */ 319 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 320 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 321 1, 1, 2 /* BlockWidth/Height,Bytes */ 322 }, 323 { 324 MESA_FORMAT_Z24_S8, /* Name */ 325 "MESA_FORMAT_Z24_S8", /* StrName */ 326 GL_DEPTH_STENCIL, /* BaseFormat */ 327 GL_UNSIGNED_INT, /* DataType */ 328 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 329 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ 330 1, 1, 4 /* BlockWidth/Height,Bytes */ 331 }, 332 { 333 MESA_FORMAT_S8_Z24, /* Name */ 334 "MESA_FORMAT_S8_Z24", /* StrName */ 335 GL_DEPTH_STENCIL, /* BaseFormat */ 336 GL_UNSIGNED_INT, /* DataType */ 337 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 338 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ 339 1, 1, 4 /* BlockWidth/Height,Bytes */ 340 }, 341 { 342 MESA_FORMAT_Z16, /* Name */ 343 "MESA_FORMAT_Z16", /* StrName */ 344 GL_DEPTH_COMPONENT, /* BaseFormat */ 345 GL_UNSIGNED_INT, /* DataType */ 346 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 347 0, 0, 0, 16, 0, /* Lum/Int/Index/Depth/StencilBits */ 348 1, 1, 2 /* BlockWidth/Height,Bytes */ 349 }, 350 { 351 MESA_FORMAT_X8_Z24, /* Name */ 352 "MESA_FORMAT_X8_Z24", /* StrName */ 353 GL_DEPTH_COMPONENT, /* BaseFormat */ 354 GL_UNSIGNED_INT, /* DataType */ 355 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 356 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ 357 1, 1, 4 /* BlockWidth/Height,Bytes */ 358 }, 359 { 360 MESA_FORMAT_Z24_X8, /* Name */ 361 "MESA_FORMAT_Z24_X8", /* StrName */ 362 GL_DEPTH_COMPONENT, /* BaseFormat */ 363 GL_UNSIGNED_INT, /* DataType */ 364 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 365 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ 366 1, 1, 4 /* BlockWidth/Height,Bytes */ 367 }, 368 { 369 MESA_FORMAT_Z32, /* Name */ 370 "MESA_FORMAT_Z32", /* StrName */ 371 GL_DEPTH_COMPONENT, /* BaseFormat */ 372 GL_UNSIGNED_INT, /* DataType */ 373 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 374 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */ 375 1, 1, 4 /* BlockWidth/Height,Bytes */ 376 }, 377 { 378 MESA_FORMAT_S8, /* Name */ 379 "MESA_FORMAT_S8", /* StrName */ 380 GL_STENCIL_INDEX, /* BaseFormat */ 381 GL_UNSIGNED_INT, /* DataType */ 382 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 383 0, 0, 0, 0, 8, /* Lum/Int/Index/Depth/StencilBits */ 384 1, 1, 1 /* BlockWidth/Height,Bytes */ 385 }, 386 { 387 MESA_FORMAT_SRGB8, 388 "MESA_FORMAT_SRGB8", 389 GL_RGB, 390 GL_UNSIGNED_NORMALIZED, 391 8, 8, 8, 0, 392 0, 0, 0, 0, 0, 393 1, 1, 3 394 }, 395 { 396 MESA_FORMAT_SRGBA8, 397 "MESA_FORMAT_SRGBA8", 398 GL_RGBA, 399 GL_UNSIGNED_NORMALIZED, 400 8, 8, 8, 8, 401 0, 0, 0, 0, 0, 402 1, 1, 4 403 }, 404 { 405 MESA_FORMAT_SARGB8, 406 "MESA_FORMAT_SARGB8", 407 GL_RGBA, 408 GL_UNSIGNED_NORMALIZED, 409 8, 8, 8, 8, 410 0, 0, 0, 0, 0, 411 1, 1, 4 412 }, 413 { 414 MESA_FORMAT_SL8, 415 "MESA_FORMAT_SL8", 416 GL_LUMINANCE, 417 GL_UNSIGNED_NORMALIZED, 418 0, 0, 0, 0, 419 8, 0, 0, 0, 0, 420 1, 1, 1 421 }, 422 { 423 MESA_FORMAT_SLA8, 424 "MESA_FORMAT_SLA8", 425 GL_LUMINANCE_ALPHA, 426 GL_UNSIGNED_NORMALIZED, 427 0, 0, 0, 8, 428 8, 0, 0, 0, 0, 429 1, 1, 2 430 }, 431 { 432 MESA_FORMAT_SRGB_DXT1, /* Name */ 433 "MESA_FORMAT_SRGB_DXT1", /* StrName */ 434 GL_RGB, /* BaseFormat */ 435 GL_UNSIGNED_NORMALIZED, /* DataType */ 436 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ 437 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 438 4, 4, 8 /* 8 bytes per 4x4 block */ 439 }, 440 { 441 MESA_FORMAT_SRGBA_DXT1, 442 "MESA_FORMAT_SRGBA_DXT1", 443 GL_RGBA, 444 GL_UNSIGNED_NORMALIZED, 445 4, 4, 4, 4, 446 0, 0, 0, 0, 0, 447 4, 4, 8 /* 8 bytes per 4x4 block */ 448 }, 449 { 450 MESA_FORMAT_SRGBA_DXT3, 451 "MESA_FORMAT_SRGBA_DXT3", 452 GL_RGBA, 453 GL_UNSIGNED_NORMALIZED, 454 4, 4, 4, 4, 455 0, 0, 0, 0, 0, 456 4, 4, 16 /* 16 bytes per 4x4 block */ 457 }, 458 { 459 MESA_FORMAT_SRGBA_DXT5, 460 "MESA_FORMAT_SRGBA_DXT5", 461 GL_RGBA, 462 GL_UNSIGNED_NORMALIZED, 463 4, 4, 4, 4, 464 0, 0, 0, 0, 0, 465 4, 4, 16 /* 16 bytes per 4x4 block */ 466 }, 467 468 { 469 MESA_FORMAT_RGB_FXT1, 470 "MESA_FORMAT_RGB_FXT1", 471 GL_RGB, 472 GL_UNSIGNED_NORMALIZED, 473 4, 4, 4, 0, /* approx Red/Green/BlueBits */ 474 0, 0, 0, 0, 0, 475 8, 4, 16 /* 16 bytes per 8x4 block */ 476 }, 477 { 478 MESA_FORMAT_RGBA_FXT1, 479 "MESA_FORMAT_RGBA_FXT1", 480 GL_RGBA, 481 GL_UNSIGNED_NORMALIZED, 482 4, 4, 4, 1, /* approx Red/Green/Blue/AlphaBits */ 483 0, 0, 0, 0, 0, 484 8, 4, 16 /* 16 bytes per 8x4 block */ 485 }, 486 487 { 488 MESA_FORMAT_RGB_DXT1, /* Name */ 489 "MESA_FORMAT_RGB_DXT1", /* StrName */ 490 GL_RGB, /* BaseFormat */ 491 GL_UNSIGNED_NORMALIZED, /* DataType */ 492 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ 493 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ 494 4, 4, 8 /* 8 bytes per 4x4 block */ 495 }, 496 { 497 MESA_FORMAT_RGBA_DXT1, 498 "MESA_FORMAT_RGBA_DXT1", 499 GL_RGBA, 500 GL_UNSIGNED_NORMALIZED, 501 4, 4, 4, 4, 502 0, 0, 0, 0, 0, 503 4, 4, 8 /* 8 bytes per 4x4 block */ 504 }, 505 { 506 MESA_FORMAT_RGBA_DXT3, 507 "MESA_FORMAT_RGBA_DXT3", 508 GL_RGBA, 509 GL_UNSIGNED_NORMALIZED, 510 4, 4, 4, 4, 511 0, 0, 0, 0, 0, 512 4, 4, 16 /* 16 bytes per 4x4 block */ 513 }, 514 { 515 MESA_FORMAT_RGBA_DXT5, 516 "MESA_FORMAT_RGBA_DXT5", 517 GL_RGBA, 518 GL_UNSIGNED_NORMALIZED, 519 4, 4, 4, 4, 520 0, 0, 0, 0, 0, 521 4, 4, 16 /* 16 bytes per 4x4 block */ 522 }, 523 { 524 MESA_FORMAT_RGBA_FLOAT32, 525 "MESA_FORMAT_RGBA_FLOAT32", 526 GL_RGBA, 527 GL_FLOAT, 528 32, 32, 32, 32, 529 0, 0, 0, 0, 0, 530 1, 1, 16 531 }, 532 { 533 MESA_FORMAT_RGBA_FLOAT16, 534 "MESA_FORMAT_RGBA_FLOAT16", 535 GL_RGBA, 536 GL_FLOAT, 537 16, 16, 16, 16, 538 0, 0, 0, 0, 0, 539 1, 1, 8 540 }, 541 { 542 MESA_FORMAT_RGB_FLOAT32, 543 "MESA_FORMAT_RGB_FLOAT32", 544 GL_RGB, 545 GL_FLOAT, 546 32, 32, 32, 0, 547 0, 0, 0, 0, 0, 548 1, 1, 12 549 }, 550 { 551 MESA_FORMAT_RGB_FLOAT16, 552 "MESA_FORMAT_RGB_FLOAT16", 553 GL_RGB, 554 GL_FLOAT, 555 16, 16, 16, 0, 556 0, 0, 0, 0, 0, 557 1, 1, 6 558 }, 559 { 560 MESA_FORMAT_ALPHA_FLOAT32, 561 "MESA_FORMAT_ALPHA_FLOAT32", 562 GL_ALPHA, 563 GL_FLOAT, 564 0, 0, 0, 32, 565 0, 0, 0, 0, 0, 566 1, 1, 4 567 }, 568 { 569 MESA_FORMAT_ALPHA_FLOAT16, 570 "MESA_FORMAT_ALPHA_FLOAT16", 571 GL_ALPHA, 572 GL_FLOAT, 573 0, 0, 0, 16, 574 0, 0, 0, 0, 0, 575 1, 1, 2 576 }, 577 { 578 MESA_FORMAT_LUMINANCE_FLOAT32, 579 "MESA_FORMAT_LUMINANCE_FLOAT32", 580 GL_ALPHA, 581 GL_FLOAT, 582 0, 0, 0, 0, 583 32, 0, 0, 0, 0, 584 1, 1, 4 585 }, 586 { 587 MESA_FORMAT_LUMINANCE_FLOAT16, 588 "MESA_FORMAT_LUMINANCE_FLOAT16", 589 GL_ALPHA, 590 GL_FLOAT, 591 0, 0, 0, 0, 592 16, 0, 0, 0, 0, 593 1, 1, 2 594 }, 595 { 596 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, 597 "MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32", 598 GL_LUMINANCE_ALPHA, 599 GL_FLOAT, 600 0, 0, 0, 32, 601 32, 0, 0, 0, 0, 602 1, 1, 8 603 }, 604 { 605 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, 606 "MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16", 607 GL_LUMINANCE_ALPHA, 608 GL_FLOAT, 609 0, 0, 0, 16, 610 16, 0, 0, 0, 0, 611 1, 1, 4 612 }, 613 { 614 MESA_FORMAT_INTENSITY_FLOAT32, 615 "MESA_FORMAT_INTENSITY_FLOAT32", 616 GL_INTENSITY, 617 GL_FLOAT, 618 0, 0, 0, 0, 619 0, 32, 0, 0, 0, 620 1, 1, 4 621 }, 622 { 623 MESA_FORMAT_INTENSITY_FLOAT16, 624 "MESA_FORMAT_INTENSITY_FLOAT16", 625 GL_INTENSITY, 626 GL_FLOAT, 627 0, 0, 0, 0, 628 0, 16, 0, 0, 0, 629 1, 1, 2 630 }, 631 { 632 MESA_FORMAT_DUDV8, 633 "MESA_FORMAT_DUDV8", 634 GL_DUDV_ATI, 635 GL_SIGNED_NORMALIZED, 636 0, 0, 0, 0, 637 0, 0, 0, 0, 0, 638 1, 1, 2 639 }, 640 { 641 MESA_FORMAT_SIGNED_RGBA8888, 642 "MESA_FORMAT_SIGNED_RGBA8888", 643 GL_RGBA, 644 GL_SIGNED_NORMALIZED, 645 8, 8, 8, 8, 646 0, 0, 0, 0, 0, 647 1, 1, 4 648 }, 649 { 650 MESA_FORMAT_SIGNED_RGBA8888_REV, 651 "MESA_FORMAT_SIGNED_RGBA8888_REV", 652 GL_RGBA, 653 GL_SIGNED_NORMALIZED, 654 8, 8, 8, 8, 655 0, 0, 0, 0, 0, 656 1, 1, 4 657 }, 658 { 659 MESA_FORMAT_SIGNED_RGBA_16, 660 "MESA_FORMAT_SIGNED_RGBA_16", 661 GL_RGBA, 662 GL_SIGNED_NORMALIZED, 663 16, 16, 16, 16, 664 0, 0, 0, 0, 0, 665 1, 1, 8 666 } 667}; 668 669 670 671static const struct gl_format_info * 672_mesa_get_format_info(gl_format format) 673{ 674 const struct gl_format_info *info = &format_info[format]; 675 assert(info->Name == format); 676 return info; 677} 678 679 680/** Return string name of format (for debugging) */ 681const char * 682_mesa_get_format_name(gl_format format) 683{ 684 const struct gl_format_info *info = _mesa_get_format_info(format); 685 ASSERT(info->BytesPerBlock); 686 return info->StrName; 687} 688 689 690 691/** 692 * Return bytes needed to store a block of pixels in the given format. 693 * Normally, a block is 1x1 (a single pixel). But for compressed formats 694 * a block may be 4x4 or 8x4, etc. 695 */ 696GLuint 697_mesa_get_format_bytes(gl_format format) 698{ 699 const struct gl_format_info *info = _mesa_get_format_info(format); 700 ASSERT(info->BytesPerBlock); 701 return info->BytesPerBlock; 702} 703 704 705/** 706 * Return bits per component for the given format. 707 * \param format one of MESA_FORMAT_x 708 * \param pname the component, such as GL_RED_BITS, GL_TEXTURE_BLUE_BITS, etc. 709 */ 710GLint 711_mesa_get_format_bits(gl_format format, GLenum pname) 712{ 713 const struct gl_format_info *info = _mesa_get_format_info(format); 714 715 switch (pname) { 716 case GL_RED_BITS: 717 case GL_TEXTURE_RED_SIZE: 718 case GL_RENDERBUFFER_RED_SIZE_EXT: 719 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 720 return info->RedBits; 721 case GL_GREEN_BITS: 722 case GL_TEXTURE_GREEN_SIZE: 723 case GL_RENDERBUFFER_GREEN_SIZE_EXT: 724 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 725 return info->GreenBits; 726 case GL_BLUE_BITS: 727 case GL_TEXTURE_BLUE_SIZE: 728 case GL_RENDERBUFFER_BLUE_SIZE_EXT: 729 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 730 return info->BlueBits; 731 case GL_ALPHA_BITS: 732 case GL_TEXTURE_ALPHA_SIZE: 733 case GL_RENDERBUFFER_ALPHA_SIZE_EXT: 734 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 735 return info->AlphaBits; 736 case GL_TEXTURE_INTENSITY_SIZE: 737 return info->IntensityBits; 738 case GL_TEXTURE_LUMINANCE_SIZE: 739 return info->LuminanceBits; 740 case GL_INDEX_BITS: 741 case GL_TEXTURE_INDEX_SIZE_EXT: 742 return info->IndexBits; 743 case GL_DEPTH_BITS: 744 case GL_TEXTURE_DEPTH_SIZE_ARB: 745 case GL_RENDERBUFFER_DEPTH_SIZE_EXT: 746 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 747 return info->DepthBits; 748 case GL_STENCIL_BITS: 749 case GL_TEXTURE_STENCIL_SIZE_EXT: 750 case GL_RENDERBUFFER_STENCIL_SIZE_EXT: 751 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 752 return info->StencilBits; 753 default: 754 _mesa_problem(NULL, "bad pname in _mesa_get_format_bits()"); 755 return 0; 756 } 757} 758 759 760/** 761 * Return the data type (or more specifically, the data representation) 762 * for the given format. 763 * The return value will be one of: 764 * GL_UNSIGNED_NORMALIZED = unsigned int representing [0,1] 765 * GL_SIGNED_NORMALIZED = signed int representing [-1, 1] 766 * GL_UNSIGNED_INT = an ordinary unsigned integer 767 * GL_FLOAT = an ordinary float 768 */ 769GLenum 770_mesa_get_format_datatype(gl_format format) 771{ 772 const struct gl_format_info *info = _mesa_get_format_info(format); 773 return info->DataType; 774} 775 776 777/** 778 * Return the basic format for the given type. The result will be 779 * one of GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, 780 * GL_INTENSITY, GL_YCBCR_MESA, GL_COLOR_INDEX, GL_DEPTH_COMPONENT, 781 * GL_STENCIL_INDEX, GL_DEPTH_STENCIL. 782 */ 783GLenum 784_mesa_get_format_base_format(gl_format format) 785{ 786 const struct gl_format_info *info = _mesa_get_format_info(format); 787 return info->BaseFormat; 788} 789 790 791/** 792 * Return the block size (in pixels) for the given format. Normally 793 * the block size is 1x1. But compressed formats will have block sizes 794 * of 4x4 or 8x4 pixels, etc. 795 * \param bw returns block width in pixels 796 * \param bh returns block height in pixels 797 */ 798void 799_mesa_get_format_block_size(gl_format format, GLuint *bw, GLuint *bh) 800{ 801 const struct gl_format_info *info = _mesa_get_format_info(format); 802 *bw = info->BlockWidth; 803 *bh = info->BlockHeight; 804} 805 806 807/** Is the given format a compressed format? */ 808GLboolean 809_mesa_is_format_compressed(gl_format format) 810{ 811 const struct gl_format_info *info = _mesa_get_format_info(format); 812 return info->BlockWidth > 1 || info->BlockHeight > 1; 813} 814 815 816/** 817 * Return color encoding for given format. 818 * \return GL_LINEAR or GL_SRGB 819 */ 820GLenum 821_mesa_get_format_color_encoding(gl_format format) 822{ 823 /* XXX this info should be encoded in gl_format_info */ 824 switch (format) { 825 case MESA_FORMAT_SRGB8: 826 case MESA_FORMAT_SRGBA8: 827 case MESA_FORMAT_SARGB8: 828 case MESA_FORMAT_SL8: 829 case MESA_FORMAT_SLA8: 830 case MESA_FORMAT_SRGB_DXT1: 831 case MESA_FORMAT_SRGBA_DXT1: 832 case MESA_FORMAT_SRGBA_DXT3: 833 case MESA_FORMAT_SRGBA_DXT5: 834 return GL_SRGB; 835 default: 836 return GL_LINEAR; 837 } 838} 839 840 841/** 842 * Return number of bytes needed to store an image of the given size 843 * in the given format. 844 */ 845GLuint 846_mesa_format_image_size(gl_format format, GLsizei width, 847 GLsizei height, GLsizei depth) 848{ 849 const struct gl_format_info *info = _mesa_get_format_info(format); 850 /* Strictly speaking, a conditional isn't needed here */ 851 if (info->BlockWidth > 1 || info->BlockHeight > 1) { 852 /* compressed format */ 853 const GLuint bw = info->BlockWidth, bh = info->BlockHeight; 854 const GLuint wblocks = (width + bw - 1) / bw; 855 const GLuint hblocks = (height + bh - 1) / bh; 856 const GLuint sz = wblocks * hblocks * info->BytesPerBlock; 857 return sz; 858 } 859 else { 860 /* non-compressed */ 861 const GLuint sz = width * height * depth * info->BytesPerBlock; 862 return sz; 863 } 864} 865 866 867 868GLint 869_mesa_format_row_stride(gl_format format, GLsizei width) 870{ 871 const struct gl_format_info *info = _mesa_get_format_info(format); 872 /* Strictly speaking, a conditional isn't needed here */ 873 if (info->BlockWidth > 1 || info->BlockHeight > 1) { 874 /* compressed format */ 875 const GLuint bw = info->BlockWidth; 876 const GLuint wblocks = (width + bw - 1) / bw; 877 const GLint stride = wblocks * info->BytesPerBlock; 878 return stride; 879 } 880 else { 881 const GLint stride = width * info->BytesPerBlock; 882 return stride; 883 } 884} 885 886 887 888/** 889 * Do sanity checking of the format info table. 890 */ 891void 892_mesa_test_formats(void) 893{ 894 GLuint i; 895 896 assert(Elements(format_info) == MESA_FORMAT_COUNT); 897 898 for (i = 0; i < MESA_FORMAT_COUNT; i++) { 899 const struct gl_format_info *info = _mesa_get_format_info(i); 900 assert(info); 901 902 assert(info->Name == i); 903 904 if (info->Name == MESA_FORMAT_NONE) 905 continue; 906 907 if (info->BlockWidth == 1 && info->BlockHeight == 1) { 908 if (info->RedBits > 0) { 909 GLuint t = info->RedBits + info->GreenBits 910 + info->BlueBits + info->AlphaBits; 911 assert(t / 8 == info->BytesPerBlock); 912 (void) t; 913 } 914 } 915 916 assert(info->DataType == GL_UNSIGNED_NORMALIZED || 917 info->DataType == GL_SIGNED_NORMALIZED || 918 info->DataType == GL_UNSIGNED_INT || 919 info->DataType == GL_FLOAT); 920 921 if (info->BaseFormat == GL_RGB) { 922 assert(info->RedBits > 0); 923 assert(info->GreenBits > 0); 924 assert(info->BlueBits > 0); 925 assert(info->AlphaBits == 0); 926 assert(info->LuminanceBits == 0); 927 assert(info->IntensityBits == 0); 928 } 929 else if (info->BaseFormat == GL_RGBA) { 930 assert(info->RedBits > 0); 931 assert(info->GreenBits > 0); 932 assert(info->BlueBits > 0); 933 assert(info->AlphaBits > 0); 934 assert(info->LuminanceBits == 0); 935 assert(info->IntensityBits == 0); 936 } 937 else if (info->BaseFormat == GL_LUMINANCE) { 938 assert(info->RedBits == 0); 939 assert(info->GreenBits == 0); 940 assert(info->BlueBits == 0); 941 assert(info->AlphaBits == 0); 942 assert(info->LuminanceBits > 0); 943 assert(info->IntensityBits == 0); 944 } 945 else if (info->BaseFormat == GL_INTENSITY) { 946 assert(info->RedBits == 0); 947 assert(info->GreenBits == 0); 948 assert(info->BlueBits == 0); 949 assert(info->AlphaBits == 0); 950 assert(info->LuminanceBits == 0); 951 assert(info->IntensityBits > 0); 952 } 953 954 } 955} 956 957 958 959/** 960 * Return datatype and number of components per texel for the given gl_format. 961 * Only used for mipmap generation code. 962 */ 963void 964_mesa_format_to_type_and_comps(gl_format format, 965 GLenum *datatype, GLuint *comps) 966{ 967 switch (format) { 968 case MESA_FORMAT_RGBA8888: 969 case MESA_FORMAT_RGBA8888_REV: 970 case MESA_FORMAT_ARGB8888: 971 case MESA_FORMAT_ARGB8888_REV: 972 case MESA_FORMAT_XRGB8888: 973 *datatype = GL_UNSIGNED_BYTE; 974 *comps = 4; 975 return; 976 case MESA_FORMAT_RGB888: 977 case MESA_FORMAT_BGR888: 978 *datatype = GL_UNSIGNED_BYTE; 979 *comps = 3; 980 return; 981 case MESA_FORMAT_RGB565: 982 case MESA_FORMAT_RGB565_REV: 983 *datatype = GL_UNSIGNED_SHORT_5_6_5; 984 *comps = 3; 985 return; 986 987 case MESA_FORMAT_ARGB4444: 988 case MESA_FORMAT_ARGB4444_REV: 989 *datatype = GL_UNSIGNED_SHORT_4_4_4_4; 990 *comps = 4; 991 return; 992 993 case MESA_FORMAT_ARGB1555: 994 case MESA_FORMAT_ARGB1555_REV: 995 *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; 996 *comps = 4; 997 return; 998 999 case MESA_FORMAT_AL88: 1000 case MESA_FORMAT_AL88_REV: 1001 *datatype = GL_UNSIGNED_BYTE; 1002 *comps = 2; 1003 return; 1004 1005 case MESA_FORMAT_AL1616: 1006 case MESA_FORMAT_AL1616_REV: 1007 *datatype = GL_UNSIGNED_SHORT; 1008 *comps = 2; 1009 return; 1010 1011 case MESA_FORMAT_RGB332: 1012 *datatype = GL_UNSIGNED_BYTE_3_3_2; 1013 *comps = 3; 1014 return; 1015 1016 case MESA_FORMAT_A8: 1017 case MESA_FORMAT_L8: 1018 case MESA_FORMAT_I8: 1019 case MESA_FORMAT_CI8: 1020 *datatype = GL_UNSIGNED_BYTE; 1021 *comps = 1; 1022 return; 1023 1024 case MESA_FORMAT_YCBCR: 1025 case MESA_FORMAT_YCBCR_REV: 1026 *datatype = GL_UNSIGNED_SHORT; 1027 *comps = 2; 1028 return; 1029 1030 case MESA_FORMAT_Z24_S8: 1031 *datatype = GL_UNSIGNED_INT; 1032 *comps = 1; /* XXX OK? */ 1033 return; 1034 1035 case MESA_FORMAT_S8_Z24: 1036 *datatype = GL_UNSIGNED_INT; 1037 *comps = 1; /* XXX OK? */ 1038 return; 1039 1040 case MESA_FORMAT_Z16: 1041 *datatype = GL_UNSIGNED_SHORT; 1042 *comps = 1; 1043 return; 1044 1045 case MESA_FORMAT_X8_Z24: 1046 *datatype = GL_UNSIGNED_INT; 1047 *comps = 1; 1048 return; 1049 1050 case MESA_FORMAT_Z24_X8: 1051 *datatype = GL_UNSIGNED_INT; 1052 *comps = 1; 1053 return; 1054 1055 case MESA_FORMAT_Z32: 1056 *datatype = GL_UNSIGNED_INT; 1057 *comps = 1; 1058 return; 1059 1060 case MESA_FORMAT_DUDV8: 1061 *datatype = GL_BYTE; 1062 *comps = 2; 1063 return; 1064 1065 case MESA_FORMAT_SIGNED_RGBA8888: 1066 case MESA_FORMAT_SIGNED_RGBA8888_REV: 1067 *datatype = GL_BYTE; 1068 *comps = 4; 1069 return; 1070 case MESA_FORMAT_SIGNED_RGBA_16: 1071 *datatype = GL_SHORT; 1072 *comps = 4; 1073 return; 1074 1075#if FEATURE_EXT_texture_sRGB 1076 case MESA_FORMAT_SRGB8: 1077 *datatype = GL_UNSIGNED_BYTE; 1078 *comps = 3; 1079 return; 1080 case MESA_FORMAT_SRGBA8: 1081 case MESA_FORMAT_SARGB8: 1082 *datatype = GL_UNSIGNED_BYTE; 1083 *comps = 4; 1084 return; 1085 case MESA_FORMAT_SL8: 1086 *datatype = GL_UNSIGNED_BYTE; 1087 *comps = 1; 1088 return; 1089 case MESA_FORMAT_SLA8: 1090 *datatype = GL_UNSIGNED_BYTE; 1091 *comps = 2; 1092 return; 1093#endif 1094 1095#if FEATURE_texture_fxt1 1096 case MESA_FORMAT_RGB_FXT1: 1097 case MESA_FORMAT_RGBA_FXT1: 1098#endif 1099#if FEATURE_texture_s3tc 1100 case MESA_FORMAT_RGB_DXT1: 1101 case MESA_FORMAT_RGBA_DXT1: 1102 case MESA_FORMAT_RGBA_DXT3: 1103 case MESA_FORMAT_RGBA_DXT5: 1104#if FEATURE_EXT_texture_sRGB 1105 case MESA_FORMAT_SRGB_DXT1: 1106 case MESA_FORMAT_SRGBA_DXT1: 1107 case MESA_FORMAT_SRGBA_DXT3: 1108 case MESA_FORMAT_SRGBA_DXT5: 1109#endif 1110 /* XXX generate error instead? */ 1111 *datatype = GL_UNSIGNED_BYTE; 1112 *comps = 0; 1113 return; 1114#endif 1115 1116 case MESA_FORMAT_RGBA_FLOAT32: 1117 *datatype = GL_FLOAT; 1118 *comps = 4; 1119 return; 1120 case MESA_FORMAT_RGBA_FLOAT16: 1121 *datatype = GL_HALF_FLOAT_ARB; 1122 *comps = 4; 1123 return; 1124 case MESA_FORMAT_RGB_FLOAT32: 1125 *datatype = GL_FLOAT; 1126 *comps = 3; 1127 return; 1128 case MESA_FORMAT_RGB_FLOAT16: 1129 *datatype = GL_HALF_FLOAT_ARB; 1130 *comps = 3; 1131 return; 1132 case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: 1133 *datatype = GL_FLOAT; 1134 *comps = 2; 1135 return; 1136 case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: 1137 *datatype = GL_HALF_FLOAT_ARB; 1138 *comps = 2; 1139 return; 1140 case MESA_FORMAT_ALPHA_FLOAT32: 1141 case MESA_FORMAT_LUMINANCE_FLOAT32: 1142 case MESA_FORMAT_INTENSITY_FLOAT32: 1143 *datatype = GL_FLOAT; 1144 *comps = 1; 1145 return; 1146 case MESA_FORMAT_ALPHA_FLOAT16: 1147 case MESA_FORMAT_LUMINANCE_FLOAT16: 1148 case MESA_FORMAT_INTENSITY_FLOAT16: 1149 *datatype = GL_HALF_FLOAT_ARB; 1150 *comps = 1; 1151 return; 1152 1153 default: 1154 _mesa_problem(NULL, "bad format in _mesa_format_to_type_and_comps"); 1155 *datatype = 0; 1156 *comps = 1; 1157 } 1158} 1159