165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.filterpacks.imageproc; 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.Filter; 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FilterContext; 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.Frame; 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FrameFormat; 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.GenerateFieldPort; 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.NativeProgram; 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.Program; 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.ShaderProgram; 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.format.ImageFormat; 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.Log; 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic class AutoFixFilter extends Filter { 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @GenerateFieldPort(name = "tile_size", hasDefault = true) 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mTileSize = 640; 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @GenerateFieldPort(name = "scale") 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private float mScale; 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private static final int normal_cdf[] = { 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9, 33, 50, 64, 75, 84, 92, 99, 106, 112, 117, 122, 126, 130, 134, 138, 142, 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 145, 148, 150, 154, 157, 159, 162, 164, 166, 169, 170, 173, 175, 177, 179, 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 180, 182, 184, 186, 188, 189, 190, 192, 194, 195, 197, 198, 199, 200, 202, 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218, 219, 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 234, 235, 236, 236, 237, 238, 239, 239, 240, 240, 242, 242, 243, 244, 245, 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 245, 246, 247, 247, 248, 249, 249, 250, 250, 251, 252, 253, 253, 254, 255, 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 255, 256, 256, 257, 258, 258, 259, 259, 259, 260, 261, 262, 262, 263, 263, 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 264, 264, 265, 265, 266, 267, 267, 268, 268, 269, 269, 269, 270, 270, 271, 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 272, 272, 273, 273, 274, 274, 275, 275, 276, 276, 277, 277, 277, 278, 278, 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 279, 279, 279, 280, 280, 281, 282, 282, 282, 283, 283, 284, 284, 285, 285, 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 285, 286, 286, 287, 287, 288, 288, 288, 289, 289, 289, 290, 290, 290, 291, 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 292, 292, 292, 293, 293, 294, 294, 294, 295, 295, 296, 296, 296, 297, 297, 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 297, 298, 298, 298, 299, 299, 299, 299, 300, 300, 301, 301, 302, 302, 302, 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 306, 307, 307, 307, 308, 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 308, 308, 309, 309, 309, 309, 310, 310, 310, 310, 311, 312, 312, 312, 313, 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 313, 313, 314, 314, 314, 315, 315, 315, 315, 316, 316, 316, 317, 317, 317, 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 318, 318, 318, 319, 319, 319, 319, 319, 320, 320, 320, 321, 321, 322, 322, 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 322, 323, 323, 323, 323, 324, 324, 324, 325, 325, 325, 325, 326, 326, 326, 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 327, 327, 327, 327, 328, 328, 328, 329, 329, 329, 329, 329, 330, 330, 330, 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 330, 331, 331, 332, 332, 332, 333, 333, 333, 333, 334, 334, 334, 334, 335, 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 335, 335, 336, 336, 336, 336, 337, 337, 337, 337, 338, 338, 338, 339, 339, 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 339, 339, 339, 339, 340, 340, 340, 340, 341, 341, 342, 342, 342, 342, 343, 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 343, 343, 344, 344, 344, 344, 345, 345, 345, 345, 346, 346, 346, 346, 347, 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 347, 347, 347, 348, 348, 348, 348, 349, 349, 349, 349, 349, 349, 350, 350, 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 350, 350, 351, 351, 352, 352, 352, 352, 353, 353, 353, 353, 354, 354, 354, 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 354, 355, 355, 355, 355, 356, 356, 356, 356, 357, 357, 357, 357, 358, 358, 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 358, 358, 359, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 361, 361, 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 362, 362, 362, 362, 363, 363, 363, 363, 364, 364, 364, 364, 365, 365, 365, 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 365, 366, 366, 366, 366, 366, 367, 367, 367, 367, 368, 368, 368, 368, 369, 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 369, 369, 369, 369, 369, 370, 370, 370, 370, 370, 371, 371, 372, 372, 372, 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 372, 373, 373, 373, 373, 374, 374, 374, 374, 374, 375, 375, 375, 375, 376, 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 376, 376, 376, 377, 377, 377, 377, 378, 378, 378, 378, 378, 379, 379, 379, 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 379, 379, 379, 380, 380, 380, 380, 381, 381, 381, 382, 382, 382, 382, 383, 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 383, 383, 383, 384, 384, 384, 384, 385, 385, 385, 385, 385, 386, 386, 386, 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 386, 387, 387, 387, 387, 388, 388, 388, 388, 388, 389, 389, 389, 389, 389, 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 389, 390, 390, 390, 390, 391, 391, 392, 392, 392, 392, 392, 393, 393, 393, 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 393, 394, 394, 394, 394, 395, 395, 395, 395, 396, 396, 396, 396, 396, 397, 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 397, 397, 397, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, 400, 400, 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 400, 400, 400, 401, 401, 402, 402, 402, 402, 403, 403, 403, 403, 404, 404, 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 404, 404, 405, 405, 405, 405, 406, 406, 406, 406, 406, 407, 407, 407, 407, 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 408, 408, 408, 408, 409, 409, 409, 409, 409, 409, 410, 410, 410, 410, 411, 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 411, 412, 412, 412, 412, 413, 413, 413, 413, 414, 414, 414, 414, 415, 415, 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 415, 415, 416, 416, 416, 416, 417, 417, 417, 417, 418, 418, 418, 418, 419, 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 419, 419, 419, 419, 419, 420, 420, 420, 420, 421, 421, 422, 422, 422, 422, 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 423, 423, 423, 423, 424, 424, 424, 425, 425, 425, 425, 426, 426, 426, 426, 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 427, 427, 427, 427, 428, 428, 428, 429, 429, 429, 429, 429, 429, 430, 430, 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 430, 430, 431, 431, 432, 432, 432, 433, 433, 433, 433, 434, 434, 434, 435, 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 435, 435, 435, 436, 436, 436, 436, 437, 437, 437, 438, 438, 438, 438, 439, 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 439, 439, 439, 439, 440, 440, 440, 441, 441, 442, 442, 442, 443, 443, 443, 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 443, 444, 444, 444, 445, 445, 445, 446, 446, 446, 446, 447, 447, 447, 448, 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 448, 448, 449, 449, 449, 449, 449, 450, 450, 450, 451, 451, 452, 452, 452, 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 453, 453, 453, 454, 454, 454, 455, 455, 455, 456, 456, 456, 457, 457, 457, 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 458, 458, 458, 459, 459, 459, 459, 460, 460, 460, 461, 461, 462, 462, 462, 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 463, 463, 463, 464, 464, 465, 465, 465, 466, 466, 466, 467, 467, 467, 468, 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 468, 469, 469, 469, 469, 470, 470, 470, 471, 472, 472, 472, 473, 473, 474, 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 474, 474, 475, 475, 476, 476, 476, 477, 477, 478, 478, 478, 479, 479, 479, 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 480, 480, 480, 481, 482, 482, 483, 483, 484, 484, 484, 485, 485, 486, 486, 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 487, 487, 488, 488, 488, 489, 489, 489, 490, 490, 491, 492, 492, 493, 493, 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 494, 494, 495, 495, 496, 496, 497, 497, 498, 498, 499, 499, 499, 500, 501, 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 502, 502, 503, 503, 504, 504, 505, 505, 506, 507, 507, 508, 508, 509, 509, 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 510, 510, 511, 512, 513, 513, 514, 515, 515, 516, 517, 517, 518, 519, 519, 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 519, 520, 521, 522, 523, 524, 524, 525, 526, 526, 527, 528, 529, 529, 530, 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 531, 532, 533, 534, 535, 535, 536, 537, 538, 539, 539, 540, 542, 543, 544, 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 545, 546, 547, 548, 549, 549, 550, 552, 553, 554, 555, 556, 558, 559, 559, 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 561, 562, 564, 565, 566, 568, 569, 570, 572, 574, 575, 577, 578, 579, 582, 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 583, 585, 587, 589, 590, 593, 595, 597, 599, 602, 604, 607, 609, 612, 615, 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 618, 620, 624, 628, 631, 635, 639, 644, 649, 654, 659, 666, 673, 680, 690, 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 700, 714 }; 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final String mAutoFixShader = 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "precision mediump float;\n" + 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform sampler2D tex_sampler_0;\n" + 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform sampler2D tex_sampler_1;\n" + 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform sampler2D tex_sampler_2;\n" + 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float scale;\n" + 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float shift_scale;\n" + 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float hist_offset;\n" + 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float hist_scale;\n" + 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float density_offset;\n" + 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "uniform float density_scale;\n" + 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "varying vec2 v_texcoord;\n" + 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "void main() {\n" + 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " const vec3 weights = vec3(0.33333, 0.33333, 0.33333);\n" + 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" + 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float energy = dot(color.rgb, weights);\n" + 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float mask_value = energy - 0.5;\n" + 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float alpha;\n" + 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " if (mask_value > 0.0) {\n" + 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " alpha = (pow(2.0 * mask_value, 1.5) - 1.0) * scale + 1.0;\n" + 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " } else { \n" + 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " alpha = (pow(2.0 * mask_value, 2.0) - 1.0) * scale + 1.0;\n" + 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " }\n" + 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float index = energy * hist_scale + hist_offset;\n" + 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " vec4 temp = texture2D(tex_sampler_1, vec2(index, 0.5));\n" + 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float value = temp.g + temp.r * shift_scale;\n" + 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " index = value * density_scale + density_offset;\n" + 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " temp = texture2D(tex_sampler_2, vec2(index, 0.5));\n" + 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " value = temp.g + temp.r * shift_scale;\n" + 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float dst_energy = energy * alpha + value * (1.0 - alpha);\n" + 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " float max_energy = energy / max(color.r, max(color.g, color.b));\n" + 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " if (dst_energy > max_energy) {\n" + 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " dst_energy = max_energy;\n" + 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " }\n" + 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " if (energy == 0.0) {\n" + 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " gl_FragColor = color;\n" + 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " } else {\n" + 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " gl_FragColor = vec4(color.rgb * dst_energy / energy, color.a);\n" + 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn " }\n" + 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "}\n"; 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Program mShaderProgram; 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Program mNativeProgram; 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mWidth = 0; 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mHeight = 0; 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mTarget = FrameFormat.TARGET_UNSPECIFIED; 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Frame mHistFrame; 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private Frame mDensityFrame; 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public AutoFixFilter(String name) { 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn super(name); 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void setupPorts() { 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA)); 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addOutputBasedOnInput("image", "image"); 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) { 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return inputFormat; 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void initProgram(FilterContext context, int target) { 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn switch (target) { 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case FrameFormat.TARGET_GPU: 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ShaderProgram shaderProgram = new ShaderProgram(context, mAutoFixShader); 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn shaderProgram.setMaximumTileSize(mTileSize); 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram = shaderProgram; 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn break; 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn default: 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Filter Sharpen does not support frames of " + 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "target " + target + "!"); 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mTarget = target; 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private void initParameters() { 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("shift_scale", 1.0f / 256f); 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("hist_offset", 0.5f / 766f); 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("hist_scale", 765f / 766f); 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("density_offset", 0.5f / 1024f); 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("density_scale", 1023f / 1024f); 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("scale", mScale); 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void prepare(FilterContext context) { 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int densityDim = 1024; 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int histDim = 255 * 3 + 1; 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn long precision = (256l * 256l - 1l); 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int[] densityTable = new int[densityDim]; 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (int i = 0; i < densityDim; ++i) { 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn long temp = normal_cdf[i] * precision / histDim; 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn densityTable[i] = (int) temp; 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat densityFormat = ImageFormat.create(densityDim, 1, 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ImageFormat.COLORSPACE_RGBA, 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat.TARGET_GPU); 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDensityFrame = context.getFrameManager().newFrame(densityFormat); 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDensityFrame.setInts(densityTable); 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void tearDown(FilterContext context) { 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mDensityFrame != null) { 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDensityFrame.release(); 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mDensityFrame = null; 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mHistFrame != null) { 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHistFrame.release(); 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHistFrame = null; 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void fieldPortValueUpdated(String name, FilterContext context) { 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mShaderProgram != null) { 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.setHostValue("scale", mScale); 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn @Override 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void process(FilterContext context) { 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get input frame 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Frame input = pullInput("image"); 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat inputFormat = input.getFormat(); 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create program if not created already 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mShaderProgram == null || inputFormat.getTarget() != mTarget) { 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initProgram(context, inputFormat.getTarget()); 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initParameters(); 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Check if the frame size has changed 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) { 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mWidth = inputFormat.getWidth(); 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHeight = inputFormat.getHeight(); 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn createHistogramFrame(context, mWidth, mHeight, input.getInts()); 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create output frame 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Frame output = context.getFrameManager().newFrame(inputFormat); 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Process 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Frame[] inputs = {input, mHistFrame, mDensityFrame}; 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mShaderProgram.process(inputs, output); 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Push output 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn pushOutput("image", output); 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Release pushed frame 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn output.release(); 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private void createHistogramFrame(FilterContext context, int width, int height, int[] data) { 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int histDims = 255 * 3 + 1; 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int[] histArray = new int[histDims]; 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn float border_thickness_ratio = 0.05f; 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int y_border_thickness = (int) (height * border_thickness_ratio); 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int x_border_thickness = (int) (width * border_thickness_ratio); 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int pixels = (width - 2 * x_border_thickness) * (height - 2 * y_border_thickness); 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn float count = 0f; 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (int y = y_border_thickness; y < height - y_border_thickness; ++y) { 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (int x = x_border_thickness; x < width - x_border_thickness; ++x) { 28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int index = y * width + x; 28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int energy = (data[index] & 0xFF) + ((data[index] >> 8) & 0xFF) + 28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ((data[index] >> 16) & 0xFF); 28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn histArray[energy] ++; 28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (int i = 1; i < histDims; i++) { 29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn histArray[i] += histArray[i-1]; 29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (int i = 0; i < histDims; i++) { 29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn long temp = (256 * 256 - 1l) * histArray[i] / pixels; 29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn histArray[i] = (int) temp; 29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat shaderHistFormat = ImageFormat.create(histDims, 1, 30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ImageFormat.COLORSPACE_RGBA, 30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat.TARGET_GPU); 30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mHistFrame != null) 30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHistFrame.release(); 30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHistFrame = context.getFrameManager().newFrame(shaderHistFormat); 30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mHistFrame.setInts(histArray); 30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 310