214 pRasInfo->scanStride = 0; 215 } else { 216 pRasInfo->rasBase = (void *) 217 (((uintptr_t) bipriv->base) + bisdo->offset); 218 pRasInfo->pixelStride = bisdo->pixStr; 219 pRasInfo->pixelBitOffset = bisdo->bitoffset; 220 pRasInfo->scanStride = bisdo->scanStr; 221 } 222 if (bipriv->lutbase == NULL) { 223 pRasInfo->lutBase = NULL; 224 pRasInfo->lutSize = 0; 225 } else { 226 pRasInfo->lutBase = bipriv->lutbase; 227 pRasInfo->lutSize = bisdo->lutsize; 228 } 229 if (bipriv->cData == NULL) { 230 pRasInfo->invColorTable = NULL; 231 pRasInfo->redErrTable = NULL; 232 pRasInfo->grnErrTable = NULL; 233 pRasInfo->bluErrTable = NULL; 234 } else { 235 pRasInfo->invColorTable = bipriv->cData->img_clr_tbl; 236 pRasInfo->redErrTable = bipriv->cData->img_oda_red; 237 pRasInfo->grnErrTable = bipriv->cData->img_oda_green; 238 pRasInfo->bluErrTable = bipriv->cData->img_oda_blue; 239 pRasInfo->invGrayTable = bipriv->cData->pGrayInverseLutData; 240 } 241 } 242 243 static void BufImg_Release(JNIEnv *env, 244 SurfaceDataOps *ops, 245 SurfaceDataRasInfo *pRasInfo) 246 { 247 BufImgSDOps *bisdo = (BufImgSDOps *)ops; 248 BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv); 249 250 if (bipriv->base != NULL) { 251 jint mode = (((bipriv->lockFlags & (SD_LOCK_WRITE)) != 0) 252 ? 0 : JNI_ABORT); 253 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->array, 254 bipriv->base, mode); 255 } 256 if (bipriv->lutbase != NULL) { 257 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, 258 bipriv->lutbase, JNI_ABORT); 259 } 260 } 261 262 static ColorData *BufImg_SetupICM(JNIEnv *env, 263 BufImgSDOps *bisdo) 264 { 265 ColorData *cData = NULL; 266 jobject colorData; 267 268 if (JNU_IsNull(env, bisdo->icm)) { 269 return (ColorData *) NULL; 270 } 271 272 colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID); 273 274 if (JNU_IsNull(env, colorData)) { 275 if (JNU_IsNull(env, clsICMCD)) { 276 // we are unable to create a wrapper object 277 return (ColorData*)NULL; 278 } 279 } else { 280 cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID); 281 } 282 283 if (cData != NULL) { 284 return cData; 285 } 286 287 cData = (ColorData*)calloc(1, sizeof(ColorData)); 288 289 if (cData != NULL) { 290 jboolean allGray 291 = (*env)->GetBooleanField(env, bisdo->icm, allGrayID); 292 int *pRgb = (int *) 293 ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL)); 294 295 if (pRgb == NULL) { 296 free(cData); 297 return (ColorData*)NULL; 298 } 299 300 cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32); 301 if (allGray == JNI_TRUE) { 302 initInverseGrayLut(pRgb, bisdo->lutsize, cData); 303 } 304 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb, 305 JNI_ABORT); 306 307 initDitherTables(cData); 308 309 if (JNU_IsNull(env, colorData)) { 310 jlong pData = ptr_to_jlong(cData); 311 colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData); 312 313 if ((*env)->ExceptionCheck(env)) 314 { 315 free(cData); 316 return (ColorData*)NULL; 317 } 318 319 (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData); 320 } | 214 pRasInfo->scanStride = 0; 215 } else { 216 pRasInfo->rasBase = (void *) 217 (((uintptr_t) bipriv->base) + bisdo->offset); 218 pRasInfo->pixelStride = bisdo->pixStr; 219 pRasInfo->pixelBitOffset = bisdo->bitoffset; 220 pRasInfo->scanStride = bisdo->scanStr; 221 } 222 if (bipriv->lutbase == NULL) { 223 pRasInfo->lutBase = NULL; 224 pRasInfo->lutSize = 0; 225 } else { 226 pRasInfo->lutBase = bipriv->lutbase; 227 pRasInfo->lutSize = bisdo->lutsize; 228 } 229 if (bipriv->cData == NULL) { 230 pRasInfo->invColorTable = NULL; 231 pRasInfo->redErrTable = NULL; 232 pRasInfo->grnErrTable = NULL; 233 pRasInfo->bluErrTable = NULL; 234 pRasInfo->representsPrimary = 0; 235 } else { 236 pRasInfo->invColorTable = bipriv->cData->img_clr_tbl; 237 pRasInfo->redErrTable = bipriv->cData->img_oda_red; 238 pRasInfo->grnErrTable = bipriv->cData->img_oda_green; 239 pRasInfo->bluErrTable = bipriv->cData->img_oda_blue; 240 pRasInfo->invGrayTable = bipriv->cData->pGrayInverseLutData; 241 pRasInfo->representsPrimary = bipriv->cData->representsPrimary; 242 } 243 } 244 245 static void BufImg_Release(JNIEnv *env, 246 SurfaceDataOps *ops, 247 SurfaceDataRasInfo *pRasInfo) 248 { 249 BufImgSDOps *bisdo = (BufImgSDOps *)ops; 250 BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv); 251 252 if (bipriv->base != NULL) { 253 jint mode = (((bipriv->lockFlags & (SD_LOCK_WRITE)) != 0) 254 ? 0 : JNI_ABORT); 255 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->array, 256 bipriv->base, mode); 257 } 258 if (bipriv->lutbase != NULL) { 259 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, 260 bipriv->lutbase, JNI_ABORT); 261 } 262 } 263 264 static jboolean calculatePrimaryColorsAprroximation(int* cmap, unsigned char* cube, int cube_size) { 265 int i, j, k; 266 jboolean represents_primary = JNI_TRUE; 267 int index, value, color; 268 // maximum variaton allowed for r,g,b values 269 int dr, dg, db; 270 // values calculated from cmap 271 int r, g, b; 272 // maximum variation allowed for r, g, b values for primary colors 273 int delta = 5; 274 // get the primary color cmap indices from corner of inverse color table 275 for (i = 0; i < cube_size; i += (cube_size - 1)) { 276 for (j = 0; j < cube_size; j += (cube_size - 1)) { 277 for (k = 0; k < cube_size; k += (cube_size - 1)) { 278 // calculate inverse color table index 279 index = i + cube_size * (j + cube_size * k); 280 // get value present in corners of inverse color table 281 value = cube[index]; 282 // use the corner values as index for cmap 283 color = cmap[value]; 284 // extract r,g,b values from cmap value 285 (r) = (color)& 0xff; 286 (g) = ((color) >> 8) & 0xff; 287 (b) = ((color) >> 16) & 0xff; 288 /* based on value of i, j, k we can set expected values for r, g, b 289 * if i,j,k is 0 then r,g,b is 0, if i,j,k is 31 then r,g,b is 255 290 */ 291 dr = (i % (cube_size - 2)) * 255; 292 dg = (j % (cube_size - 2)) * 255; 293 db = (k % (cube_size - 2)) * 255; 294 295 // if i,j,k values are 31 delta will be -5 and if i,j,k values are 0 296 // delta will be +5. if r,g,b values from cmap vary more than dr,dg,db 297 // then they dont represent primary colors properly. 298 if (i % (cube_size - 2)) { 299 dr -= delta; 300 if (r < dr) { 301 represents_primary = JNI_FALSE; 302 break; 303 } 304 } 305 else { 306 dr += delta; 307 if (r > dr) { 308 represents_primary = JNI_FALSE; 309 break; 310 } 311 } 312 if (j % (cube_size - 2)) { 313 dg -= delta; 314 if (g < dg) { 315 represents_primary = JNI_FALSE; 316 break; 317 } 318 } 319 else { 320 dg += delta; 321 if (g > dg) { 322 represents_primary = JNI_FALSE; 323 break; 324 } 325 } 326 if (k % (cube_size - 2)) { 327 db -= delta; 328 if (b < db) { 329 represents_primary = JNI_FALSE; 330 break; 331 } 332 } 333 else { 334 db += delta; 335 if (b > db) { 336 represents_primary = JNI_FALSE; 337 break; 338 } 339 } 340 } 341 } 342 } 343 return represents_primary; 344 } 345 346 static ColorData *BufImg_SetupICM(JNIEnv *env, 347 BufImgSDOps *bisdo) 348 { 349 ColorData *cData = NULL; 350 jobject colorData; 351 352 if (JNU_IsNull(env, bisdo->icm)) { 353 return (ColorData *) NULL; 354 } 355 356 colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID); 357 358 if (JNU_IsNull(env, colorData)) { 359 if (JNU_IsNull(env, clsICMCD)) { 360 // we are unable to create a wrapper object 361 return (ColorData*)NULL; 362 } 363 } else { 364 cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID); 365 } 366 367 if (cData != NULL) { 368 return cData; 369 } 370 371 cData = (ColorData*)calloc(1, sizeof(ColorData)); 372 373 if (cData != NULL) { 374 jboolean allGray 375 = (*env)->GetBooleanField(env, bisdo->icm, allGrayID); 376 int *pRgb = (int *) 377 ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL)); 378 379 if (pRgb == NULL) { 380 free(cData); 381 return (ColorData*)NULL; 382 } 383 384 cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32); 385 cData->representsPrimary = calculatePrimaryColorsAprroximation(pRgb, cData->img_clr_tbl, 32); 386 if (allGray == JNI_TRUE) { 387 initInverseGrayLut(pRgb, bisdo->lutsize, cData); 388 } 389 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb, 390 JNI_ABORT); 391 392 initDitherTables(cData); 393 394 if (JNU_IsNull(env, colorData)) { 395 jlong pData = ptr_to_jlong(cData); 396 colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData); 397 398 if ((*env)->ExceptionCheck(env)) 399 { 400 free(cData); 401 return (ColorData*)NULL; 402 } 403 404 (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData); 405 } |