From 422643b8e234b2fc122338b6d0b440b9a1e7a4a6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 12 Jan 2017 01:20:16 +0100 Subject: [PATCH 01/19] Initial refactor of RgbToYCbCr: Moved lookup tables to a separate file --- .../Color/RgbToYCbCr.LookupTables.cs | 237 ++++++++++++++++++ .../ImageSharp.Benchmarks/Color/RgbToYCbCr.cs | 234 +---------------- 2 files changed, 241 insertions(+), 230 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.LookupTables.cs diff --git a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.LookupTables.cs b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.LookupTables.cs new file mode 100644 index 000000000..18c8cb372 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.LookupTables.cs @@ -0,0 +1,237 @@ +namespace ImageSharp.Benchmarks +{ + public partial class RgbToYCbCr + { + /// + /// Scaled integer RGBA to YCbCr lookup tables + /// + private static class LookupTables + { + public static readonly int[] Y0 = + { + 0, 306, 612, 918, 1224, 1530, 1836, 2142, 2448, 2754, 3060, 3366, 3672, 3978, 4284, + 4590, 4896, 5202, 5508, 5814, 6120, 6426, 6732, 7038, 7344, 7650, 7956, 8262, 8568, + 8874, 9180, 9486, 9792, 10098, 10404, 10710, 11016, 11322, 11628, 11934, 12240, + 12546, 12852, 13158, 13464, 13770, 14076, 14382, 14688, 14994, 15300, 15606, 15912, + 16218, 16524, 16830, 17136, 17442, 17748, 18054, 18360, 18666, 18972, 19278, 19584, + 19890, 20196, 20502, 20808, 21114, 21420, 21726, 22032, 22338, 22644, 22950, 23256, + 23562, 23868, 24174, 24480, 24786, 25092, 25398, 25704, 26010, 26316, 26622, 26928, + 27234, 27540, 27846, 28152, 28458, 28764, 29070, 29376, 29682, 29988, 30294, 30600, + 30906, 31212, 31518, 31824, 32130, 32436, 32742, 33048, 33354, 33660, 33966, 34272, + 34578, 34884, 35190, 35496, 35802, 36108, 36414, 36720, 37026, 37332, 37638, 37944, + 38250, 38556, 38862, 39168, 39474, 39780, 40086, 40392, 40698, 41004, 41310, 41616, + 41922, 42228, 42534, 42840, 43146, 43452, 43758, 44064, 44370, 44676, 44982, 45288, + 45594, 45900, 46206, 46512, 46818, 47124, 47430, 47736, 48042, 48348, 48654, 48960, + 49266, 49572, 49878, 50184, 50490, 50796, 51102, 51408, 51714, 52020, 52326, 52632, + 52938, 53244, 53550, 53856, 54162, 54468, 54774, 55080, 55386, 55692, 55998, 56304, + 56610, 56916, 57222, 57528, 57834, 58140, 58446, 58752, 59058, 59364, 59670, 59976, + 60282, 60588, 60894, 61200, 61506, 61812, 62118, 62424, 62730, 63036, 63342, 63648, + 63954, 64260, 64566, 64872, 65178, 65484, 65790, 66096, 66402, 66708, 67014, 67320, + 67626, 67932, 68238, 68544, 68850, 69156, 69462, 69768, 70074, 70380, 70686, 70992, + 71298, 71604, 71910, 72216, 72522, 72828, 73134, 73440, 73746, 74052, 74358, 74664, + 74970, 75276, 75582, 75888, 76194, 76500, 76806, 77112, 77418, 77724, 78030 + }; + + public static readonly int[] Y1 = + { + 0, 601, 1202, 1803, 2404, 3005, 3606, 4207, 4808, 5409, 6010, 6611, 7212, 7813, 8414, + 9015, 9616, 10217, 10818, 11419, 12020, 12621, 13222, 13823, 14424, 15025, 15626, + 16227, 16828, 17429, 18030, 18631, 19232, 19833, 20434, 21035, 21636, 22237, 22838, + 23439, 24040, 24641, 25242, 25843, 26444, 27045, 27646, 28247, 28848, 29449, 30050, + 30651, 31252, 31853, 32454, 33055, 33656, 34257, 34858, 35459, 36060, 36661, 37262, + 37863, 38464, 39065, 39666, 40267, 40868, 41469, 42070, 42671, 43272, 43873, 44474, + 45075, 45676, 46277, 46878, 47479, 48080, 48681, 49282, 49883, 50484, 51085, 51686, + 52287, 52888, 53489, 54090, 54691, 55292, 55893, 56494, 57095, 57696, 58297, 58898, + 59499, 60100, 60701, 61302, 61903, 62504, 63105, 63706, 64307, 64908, 65509, 66110, + 66711, 67312, 67913, 68514, 69115, 69716, 70317, 70918, 71519, 72120, 72721, 73322, + 73923, 74524, 75125, 75726, 76327, 76928, 77529, 78130, 78731, 79332, 79933, 80534, + 81135, 81736, 82337, 82938, 83539, 84140, 84741, 85342, 85943, 86544, 87145, 87746, + 88347, 88948, 89549, 90150, 90751, 91352, 91953, 92554, 93155, 93756, 94357, 94958, + 95559, 96160, 96761, 97362, 97963, 98564, 99165, 99766, 100367, 100968, 101569, + 102170, 102771, 103372, 103973, 104574, 105175, 105776, 106377, 106978, 107579, + 108180, 108781, 109382, 109983, 110584, 111185, 111786, 112387, 112988, 113589, + 114190, 114791, 115392, 115993, 116594, 117195, 117796, 118397, 118998, 119599, + 120200, 120801, 121402, 122003, 122604, 123205, 123806, 124407, 125008, 125609, + 126210, 126811, 127412, 128013, 128614, 129215, 129816, 130417, 131018, 131619, + 132220, 132821, 133422, 134023, 134624, 135225, 135826, 136427, 137028, 137629, + 138230, 138831, 139432, 140033, 140634, 141235, 141836, 142437, 143038, 143639, + 144240, 144841, 145442, 146043, 146644, 147245, 147846, 148447, 149048, 149649, + 150250, 150851, 151452, 152053, 152654, 153255 + }; + + public static readonly int[] Y2 = + { + 0, 117, 234, 351, 468, 585, 702, 819, 936, 1053, 1170, 1287, 1404, 1521, 1638, 1755, + 1872, 1989, 2106, 2223, 2340, 2457, 2574, 2691, 2808, 2925, 3042, 3159, 3276, 3393, + 3510, 3627, 3744, 3861, 3978, 4095, 4212, 4329, 4446, 4563, 4680, 4797, 4914, 5031, + 5148, 5265, 5382, 5499, 5616, 5733, 5850, 5967, 6084, 6201, 6318, 6435, 6552, 6669, + 6786, 6903, 7020, 7137, 7254, 7371, 7488, 7605, 7722, 7839, 7956, 8073, 8190, 8307, + 8424, 8541, 8658, 8775, 8892, 9009, 9126, 9243, 9360, 9477, 9594, 9711, 9828, 9945, + 10062, 10179, 10296, 10413, 10530, 10647, 10764, 10881, 10998, 11115, 11232, 11349, + 11466, 11583, 11700, 11817, 11934, 12051, 12168, 12285, 12402, 12519, 12636, 12753, + 12870, 12987, 13104, 13221, 13338, 13455, 13572, 13689, 13806, 13923, 14040, 14157, + 14274, 14391, 14508, 14625, 14742, 14859, 14976, 15093, 15210, 15327, 15444, 15561, + 15678, 15795, 15912, 16029, 16146, 16263, 16380, 16497, 16614, 16731, 16848, 16965, + 17082, 17199, 17316, 17433, 17550, 17667, 17784, 17901, 18018, 18135, 18252, 18369, + 18486, 18603, 18720, 18837, 18954, 19071, 19188, 19305, 19422, 19539, 19656, 19773, + 19890, 20007, 20124, 20241, 20358, 20475, 20592, 20709, 20826, 20943, 21060, 21177, + 21294, 21411, 21528, 21645, 21762, 21879, 21996, 22113, 22230, 22347, 22464, 22581, + 22698, 22815, 22932, 23049, 23166, 23283, 23400, 23517, 23634, 23751, 23868, 23985, + 24102, 24219, 24336, 24453, 24570, 24687, 24804, 24921, 25038, 25155, 25272, 25389, + 25506, 25623, 25740, 25857, 25974, 26091, 26208, 26325, 26442, 26559, 26676, 26793, + 26910, 27027, 27144, 27261, 27378, 27495, 27612, 27729, 27846, 27963, 28080, 28197, + 28314, 28431, 28548, 28665, 28782, 28899, 29016, 29133, 29250, 29367, 29484, 29601, + 29718, 29835 + }; + + public static readonly int[] Cb0 = + { + 0, -172, -344, -516, -688, -860, -1032, -1204, -1376, -1548, -1720, -1892, + -2064, -2236, -2408, -2580, -2752, -2924, -3096, -3268, -3440, -3612, + -3784, -3956, -4128, -4300, -4472, -4644, -4816, -4988, -5160, -5332, + -5504, -5676, -5848, -6020, -6192, -6364, -6536, -6708, -6880, -7052, + -7224, -7396, -7568, -7740, -7912, -8084, -8256, -8428, -8600, -8772, + -8944, -9116, -9288, -9460, -9632, -9804, -9976, -10148, -10320, -10492, + -10664, -10836, -11008, -11180, -11352, -11524, -11696, -11868, -12040, + -12212, -12384, -12556, -12728, -12900, -13072, -13244, -13416, -13588, + -13760, -13932, -14104, -14276, -14448, -14620, -14792, -14964, -15136, + -15308, -15480, -15652, -15824, -15996, -16168, -16340, -16512, -16684, + -16856, -17028, -17200, -17372, -17544, -17716, -17888, -18060, -18232, + -18404, -18576, -18748, -18920, -19092, -19264, -19436, -19608, -19780, + -19952, -20124, -20296, -20468, -20640, -20812, -20984, -21156, -21328, + -21500, -21672, -21844, -22016, -22188, -22360, -22532, -22704, -22876, + -23048, -23220, -23392, -23564, -23736, -23908, -24080, -24252, -24424, + -24596, -24768, -24940, -25112, -25284, -25456, -25628, -25800, -25972, + -26144, -26316, -26488, -26660, -26832, -27004, -27176, -27348, -27520, + -27692, -27864, -28036, -28208, -28380, -28552, -28724, -28896, -29068, + -29240, -29412, -29584, -29756, -29928, -30100, -30272, -30444, -30616, + -30788, -30960, -31132, -31304, -31476, -31648, -31820, -31992, -32164, + -32336, -32508, -32680, -32852, -33024, -33196, -33368, -33540, -33712, + -33884, -34056, -34228, -34400, -34572, -34744, -34916, -35088, -35260, + -35432, -35604, -35776, -35948, -36120, -36292, -36464, -36636, -36808, + -36980, -37152, -37324, -37496, -37668, -37840, -38012, -38184, -38356, + -38528, -38700, -38872, -39044, -39216, -39388, -39560, -39732, -39904, + -40076, -40248, -40420, -40592, -40764, -40936, -41108, -41280, -41452, + -41624, -41796, -41968, -42140, -42312, -42484, -42656, -42828, -43000, + -43172, -43344, -43516, -43688, -43860 + }; + + public static readonly int[] Cb1 = + { + 0, 339, 678, 1017, 1356, 1695, 2034, 2373, 2712, 3051, 3390, 3729, 4068, + 4407, 4746, 5085, 5424, 5763, 6102, 6441, 6780, 7119, 7458, 7797, 8136, + 8475, 8814, 9153, 9492, 9831, 10170, 10509, 10848, 11187, 11526, 11865, + 12204, 12543, 12882, 13221, 13560, 13899, 14238, 14577, 14916, 15255, + 15594, 15933, 16272, 16611, 16950, 17289, 17628, 17967, 18306, 18645, + 18984, 19323, 19662, 20001, 20340, 20679, 21018, 21357, 21696, 22035, + 22374, 22713, 23052, 23391, 23730, 24069, 24408, 24747, 25086, 25425, + 25764, 26103, 26442, 26781, 27120, 27459, 27798, 28137, 28476, 28815, + 29154, 29493, 29832, 30171, 30510, 30849, 31188, 31527, 31866, 32205, + 32544, 32883, 33222, 33561, 33900, 34239, 34578, 34917, 35256, 35595, + 35934, 36273, 36612, 36951, 37290, 37629, 37968, 38307, 38646, 38985, + 39324, 39663, 40002, 40341, 40680, 41019, 41358, 41697, 42036, 42375, + 42714, 43053, 43392, 43731, 44070, 44409, 44748, 45087, 45426, 45765, + 46104, 46443, 46782, 47121, 47460, 47799, 48138, 48477, 48816, 49155, + 49494, 49833, 50172, 50511, 50850, 51189, 51528, 51867, 52206, 52545, + 52884, 53223, 53562, 53901, 54240, 54579, 54918, 55257, 55596, 55935, + 56274, 56613, 56952, 57291, 57630, 57969, 58308, 58647, 58986, 59325, + 59664, 60003, 60342, 60681, 61020, 61359, 61698, 62037, 62376, 62715, + 63054, 63393, 63732, 64071, 64410, 64749, 65088, 65427, 65766, 66105, + 66444, 66783, 67122, 67461, 67800, 68139, 68478, 68817, 69156, 69495, + 69834, 70173, 70512, 70851, 71190, 71529, 71868, 72207, 72546, 72885, + 73224, 73563, 73902, 74241, 74580, 74919, 75258, 75597, 75936, 76275, + 76614, 76953, 77292, 77631, 77970, 78309, 78648, 78987, 79326, 79665, + 80004, 80343, 80682, 81021, 81360, 81699, 82038, 82377, 82716, 83055, + 83394, 83733, 84072, 84411, 84750, 85089, 85428, 85767, 86106, 86445 + }; + + public static readonly int[] Cb2Cr0 = + { + 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, + 6656, 7168, 7680, 8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776, + 12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872, 16384, 16896, + 17408, 17920, 18432, 18944, 19456, 19968, 20480, 20992, 21504, 22016, + 22528, 23040, 23552, 24064, 24576, 25088, 25600, 26112, 26624, 27136, + 27648, 28160, 28672, 29184, 29696, 30208, 30720, 31232, 31744, 32256, + 32768, 33280, 33792, 34304, 34816, 35328, 35840, 36352, 36864, 37376, + 37888, 38400, 38912, 39424, 39936, 40448, 40960, 41472, 41984, 42496, + 43008, 43520, 44032, 44544, 45056, 45568, 46080, 46592, 47104, 47616, + 48128, 48640, 49152, 49664, 50176, 50688, 51200, 51712, 52224, 52736, + 53248, 53760, 54272, 54784, 55296, 55808, 56320, 56832, 57344, 57856, + 58368, 58880, 59392, 59904, 60416, 60928, 61440, 61952, 62464, 62976, + 63488, 64000, 64512, 65024, 65536, 66048, 66560, 67072, 67584, 68096, + 68608, 69120, 69632, 70144, 70656, 71168, 71680, 72192, 72704, 73216, + 73728, 74240, 74752, 75264, 75776, 76288, 76800, 77312, 77824, 78336, + 78848, 79360, 79872, 80384, 80896, 81408, 81920, 82432, 82944, 83456, + 83968, 84480, 84992, 85504, 86016, 86528, 87040, 87552, 88064, 88576, + 89088, 89600, 90112, 90624, 91136, 91648, 92160, 92672, 93184, 93696, + 94208, 94720, 95232, 95744, 96256, 96768, 97280, 97792, 98304, 98816, + 99328, 99840, 100352, 100864, 101376, 101888, 102400, 102912, 103424, + 103936, 104448, 104960, 105472, 105984, 106496, 107008, 107520, 108032, + 108544, 109056, 109568, 110080, 110592, 111104, 111616, 112128, 112640, + 113152, 113664, 114176, 114688, 115200, 115712, 116224, 116736, 117248, + 117760, 118272, 118784, 119296, 119808, 120320, 120832, 121344, 121856, + 122368, 122880, 123392, 123904, 124416, 124928, 125440, 125952, 126464, + 126976, 127488, 128000, 128512, 129024, 129536, 130048, 130560 + }; + + public static readonly int[] Cr1 = + { + 0, 429, 858, 1287, 1716, 2145, 2574, 3003, 3432, 3861, 4290, 4719, 5148, + 5577, 6006, 6435, 6864, 7293, 7722, 8151, 8580, 9009, 9438, 9867, 10296, + 10725, 11154, 11583, 12012, 12441, 12870, 13299, 13728, 14157, 14586, + 15015, 15444, 15873, 16302, 16731, 17160, 17589, 18018, 18447, 18876, + 19305, 19734, 20163, 20592, 21021, 21450, 21879, 22308, 22737, 23166, + 23595, 24024, 24453, 24882, 25311, 25740, 26169, 26598, 27027, 27456, + 27885, 28314, 28743, 29172, 29601, 30030, 30459, 30888, 31317, 31746, + 32175, 32604, 33033, 33462, 33891, 34320, 34749, 35178, 35607, 36036, + 36465, 36894, 37323, 37752, 38181, 38610, 39039, 39468, 39897, 40326, + 40755, 41184, 41613, 42042, 42471, 42900, 43329, 43758, 44187, 44616, + 45045, 45474, 45903, 46332, 46761, 47190, 47619, 48048, 48477, 48906, + 49335, 49764, 50193, 50622, 51051, 51480, 51909, 52338, 52767, 53196, + 53625, 54054, 54483, 54912, 55341, 55770, 56199, 56628, 57057, 57486, + 57915, 58344, 58773, 59202, 59631, 60060, 60489, 60918, 61347, 61776, + 62205, 62634, 63063, 63492, 63921, 64350, 64779, 65208, 65637, 66066, + 66495, 66924, 67353, 67782, 68211, 68640, 69069, 69498, 69927, 70356, + 70785, 71214, 71643, 72072, 72501, 72930, 73359, 73788, 74217, 74646, + 75075, 75504, 75933, 76362, 76791, 77220, 77649, 78078, 78507, 78936, + 79365, 79794, 80223, 80652, 81081, 81510, 81939, 82368, 82797, 83226, + 83655, 84084, 84513, 84942, 85371, 85800, 86229, 86658, 87087, 87516, + 87945, 88374, 88803, 89232, 89661, 90090, 90519, 90948, 91377, 91806, + 92235, 92664, 93093, 93522, 93951, 94380, 94809, 95238, 95667, 96096, + 96525, 96954, 97383, 97812, 98241, 98670, 99099, 99528, 99957, 100386, + 100815, 101244, 101673, 102102, 102531, 102960, 103389, 103818, 104247, + 104676, 105105, 105534, 105963, 106392, 106821, 107250, 107679, 108108, + 108537, 108966, 109395 + }; + + public static readonly int[] Cr2 = + { + 0, 83, 166, 249, 332, 415, 498, 581, 664, 747, 830, 913, 996, 1079, 1162, + 1245, 1328, 1411, 1494, 1577, 1660, 1743, 1826, 1909, 1992, 2075, 2158, + 2241, 2324, 2407, 2490, 2573, 2656, 2739, 2822, 2905, 2988, 3071, 3154, + 3237, 3320, 3403, 3486, 3569, 3652, 3735, 3818, 3901, 3984, 4067, 4150, + 4233, 4316, 4399, 4482, 4565, 4648, 4731, 4814, 4897, 4980, 5063, 5146, + 5229, 5312, 5395, 5478, 5561, 5644, 5727, 5810, 5893, 5976, 6059, 6142, + 6225, 6308, 6391, 6474, 6557, 6640, 6723, 6806, 6889, 6972, 7055, 7138, + 7221, 7304, 7387, 7470, 7553, 7636, 7719, 7802, 7885, 7968, 8051, 8134, + 8217, 8300, 8383, 8466, 8549, 8632, 8715, 8798, 8881, 8964, 9047, 9130, + 9213, 9296, 9379, 9462, 9545, 9628, 9711, 9794, 9877, 9960, 10043, 10126, + 10209, 10292, 10375, 10458, 10541, 10624, 10707, 10790, 10873, 10956, + 11039, 11122, 11205, 11288, 11371, 11454, 11537, 11620, 11703, 11786, + 11869, 11952, 12035, 12118, 12201, 12284, 12367, 12450, 12533, 12616, + 12699, 12782, 12865, 12948, 13031, 13114, 13197, 13280, 13363, 13446, + 13529, 13612, 13695, 13778, 13861, 13944, 14027, 14110, 14193, 14276, + 14359, 14442, 14525, 14608, 14691, 14774, 14857, 14940, 15023, 15106, + 15189, 15272, 15355, 15438, 15521, 15604, 15687, 15770, 15853, 15936, + 16019, 16102, 16185, 16268, 16351, 16434, 16517, 16600, 16683, 16766, + 16849, 16932, 17015, 17098, 17181, 17264, 17347, 17430, 17513, 17596, + 17679, 17762, 17845, 17928, 18011, 18094, 18177, 18260, 18343, 18426, + 18509, 18592, 18675, 18758, 18841, 18924, 19007, 19090, 19173, 19256, + 19339, 19422, 19505, 19588, 19671, 19754, 19837, 19920, 20003, 20086, + 20169, 20252, 20335, 20418, 20501, 20584, 20667, 20750, 20833, 20916, + 20999, 21082, 21165 + }; + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs index fb738021b..33bc85da0 100644 --- a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs +++ b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs @@ -4,238 +4,12 @@ using BenchmarkDotNet.Attributes; - public class RgbToYCbCr + public partial class RgbToYCbCr { private static readonly Vector3 VectorY = new Vector3(0.299F, 0.587F, 0.114F); private static readonly Vector3 VectorCb = new Vector3(-0.168736F, 0.331264F, 0.5F); private static readonly Vector3 VectorCr = new Vector3(0.5F, 0.418688F, 0.081312F); - private static readonly int[] Y0Lut = - { - 0, 306, 612, 918, 1224, 1530, 1836, 2142, 2448, 2754, 3060, 3366, 3672, 3978, 4284, - 4590, 4896, 5202, 5508, 5814, 6120, 6426, 6732, 7038, 7344, 7650, 7956, 8262, 8568, - 8874, 9180, 9486, 9792, 10098, 10404, 10710, 11016, 11322, 11628, 11934, 12240, - 12546, 12852, 13158, 13464, 13770, 14076, 14382, 14688, 14994, 15300, 15606, 15912, - 16218, 16524, 16830, 17136, 17442, 17748, 18054, 18360, 18666, 18972, 19278, 19584, - 19890, 20196, 20502, 20808, 21114, 21420, 21726, 22032, 22338, 22644, 22950, 23256, - 23562, 23868, 24174, 24480, 24786, 25092, 25398, 25704, 26010, 26316, 26622, 26928, - 27234, 27540, 27846, 28152, 28458, 28764, 29070, 29376, 29682, 29988, 30294, 30600, - 30906, 31212, 31518, 31824, 32130, 32436, 32742, 33048, 33354, 33660, 33966, 34272, - 34578, 34884, 35190, 35496, 35802, 36108, 36414, 36720, 37026, 37332, 37638, 37944, - 38250, 38556, 38862, 39168, 39474, 39780, 40086, 40392, 40698, 41004, 41310, 41616, - 41922, 42228, 42534, 42840, 43146, 43452, 43758, 44064, 44370, 44676, 44982, 45288, - 45594, 45900, 46206, 46512, 46818, 47124, 47430, 47736, 48042, 48348, 48654, 48960, - 49266, 49572, 49878, 50184, 50490, 50796, 51102, 51408, 51714, 52020, 52326, 52632, - 52938, 53244, 53550, 53856, 54162, 54468, 54774, 55080, 55386, 55692, 55998, 56304, - 56610, 56916, 57222, 57528, 57834, 58140, 58446, 58752, 59058, 59364, 59670, 59976, - 60282, 60588, 60894, 61200, 61506, 61812, 62118, 62424, 62730, 63036, 63342, 63648, - 63954, 64260, 64566, 64872, 65178, 65484, 65790, 66096, 66402, 66708, 67014, 67320, - 67626, 67932, 68238, 68544, 68850, 69156, 69462, 69768, 70074, 70380, 70686, 70992, - 71298, 71604, 71910, 72216, 72522, 72828, 73134, 73440, 73746, 74052, 74358, 74664, - 74970, 75276, 75582, 75888, 76194, 76500, 76806, 77112, 77418, 77724, 78030 - }; - - private static readonly int[] Y1Lut = - { - 0, 601, 1202, 1803, 2404, 3005, 3606, 4207, 4808, 5409, 6010, 6611, 7212, 7813, 8414, - 9015, 9616, 10217, 10818, 11419, 12020, 12621, 13222, 13823, 14424, 15025, 15626, - 16227, 16828, 17429, 18030, 18631, 19232, 19833, 20434, 21035, 21636, 22237, 22838, - 23439, 24040, 24641, 25242, 25843, 26444, 27045, 27646, 28247, 28848, 29449, 30050, - 30651, 31252, 31853, 32454, 33055, 33656, 34257, 34858, 35459, 36060, 36661, 37262, - 37863, 38464, 39065, 39666, 40267, 40868, 41469, 42070, 42671, 43272, 43873, 44474, - 45075, 45676, 46277, 46878, 47479, 48080, 48681, 49282, 49883, 50484, 51085, 51686, - 52287, 52888, 53489, 54090, 54691, 55292, 55893, 56494, 57095, 57696, 58297, 58898, - 59499, 60100, 60701, 61302, 61903, 62504, 63105, 63706, 64307, 64908, 65509, 66110, - 66711, 67312, 67913, 68514, 69115, 69716, 70317, 70918, 71519, 72120, 72721, 73322, - 73923, 74524, 75125, 75726, 76327, 76928, 77529, 78130, 78731, 79332, 79933, 80534, - 81135, 81736, 82337, 82938, 83539, 84140, 84741, 85342, 85943, 86544, 87145, 87746, - 88347, 88948, 89549, 90150, 90751, 91352, 91953, 92554, 93155, 93756, 94357, 94958, - 95559, 96160, 96761, 97362, 97963, 98564, 99165, 99766, 100367, 100968, 101569, - 102170, 102771, 103372, 103973, 104574, 105175, 105776, 106377, 106978, 107579, - 108180, 108781, 109382, 109983, 110584, 111185, 111786, 112387, 112988, 113589, - 114190, 114791, 115392, 115993, 116594, 117195, 117796, 118397, 118998, 119599, - 120200, 120801, 121402, 122003, 122604, 123205, 123806, 124407, 125008, 125609, - 126210, 126811, 127412, 128013, 128614, 129215, 129816, 130417, 131018, 131619, - 132220, 132821, 133422, 134023, 134624, 135225, 135826, 136427, 137028, 137629, - 138230, 138831, 139432, 140033, 140634, 141235, 141836, 142437, 143038, 143639, - 144240, 144841, 145442, 146043, 146644, 147245, 147846, 148447, 149048, 149649, - 150250, 150851, 151452, 152053, 152654, 153255 - }; - - private static readonly int[] Y2Lut = - { - 0, 117, 234, 351, 468, 585, 702, 819, 936, 1053, 1170, 1287, 1404, 1521, 1638, 1755, - 1872, 1989, 2106, 2223, 2340, 2457, 2574, 2691, 2808, 2925, 3042, 3159, 3276, 3393, - 3510, 3627, 3744, 3861, 3978, 4095, 4212, 4329, 4446, 4563, 4680, 4797, 4914, 5031, - 5148, 5265, 5382, 5499, 5616, 5733, 5850, 5967, 6084, 6201, 6318, 6435, 6552, 6669, - 6786, 6903, 7020, 7137, 7254, 7371, 7488, 7605, 7722, 7839, 7956, 8073, 8190, 8307, - 8424, 8541, 8658, 8775, 8892, 9009, 9126, 9243, 9360, 9477, 9594, 9711, 9828, 9945, - 10062, 10179, 10296, 10413, 10530, 10647, 10764, 10881, 10998, 11115, 11232, 11349, - 11466, 11583, 11700, 11817, 11934, 12051, 12168, 12285, 12402, 12519, 12636, 12753, - 12870, 12987, 13104, 13221, 13338, 13455, 13572, 13689, 13806, 13923, 14040, 14157, - 14274, 14391, 14508, 14625, 14742, 14859, 14976, 15093, 15210, 15327, 15444, 15561, - 15678, 15795, 15912, 16029, 16146, 16263, 16380, 16497, 16614, 16731, 16848, 16965, - 17082, 17199, 17316, 17433, 17550, 17667, 17784, 17901, 18018, 18135, 18252, 18369, - 18486, 18603, 18720, 18837, 18954, 19071, 19188, 19305, 19422, 19539, 19656, 19773, - 19890, 20007, 20124, 20241, 20358, 20475, 20592, 20709, 20826, 20943, 21060, 21177, - 21294, 21411, 21528, 21645, 21762, 21879, 21996, 22113, 22230, 22347, 22464, 22581, - 22698, 22815, 22932, 23049, 23166, 23283, 23400, 23517, 23634, 23751, 23868, 23985, - 24102, 24219, 24336, 24453, 24570, 24687, 24804, 24921, 25038, 25155, 25272, 25389, - 25506, 25623, 25740, 25857, 25974, 26091, 26208, 26325, 26442, 26559, 26676, 26793, - 26910, 27027, 27144, 27261, 27378, 27495, 27612, 27729, 27846, 27963, 28080, 28197, - 28314, 28431, 28548, 28665, 28782, 28899, 29016, 29133, 29250, 29367, 29484, 29601, - 29718, 29835 - }; - - private static readonly int[] Cb0Lut = - { - 0, -172, -344, -516, -688, -860, -1032, -1204, -1376, -1548, -1720, -1892, - -2064, -2236, -2408, -2580, -2752, -2924, -3096, -3268, -3440, -3612, - -3784, -3956, -4128, -4300, -4472, -4644, -4816, -4988, -5160, -5332, - -5504, -5676, -5848, -6020, -6192, -6364, -6536, -6708, -6880, -7052, - -7224, -7396, -7568, -7740, -7912, -8084, -8256, -8428, -8600, -8772, - -8944, -9116, -9288, -9460, -9632, -9804, -9976, -10148, -10320, -10492, - -10664, -10836, -11008, -11180, -11352, -11524, -11696, -11868, -12040, - -12212, -12384, -12556, -12728, -12900, -13072, -13244, -13416, -13588, - -13760, -13932, -14104, -14276, -14448, -14620, -14792, -14964, -15136, - -15308, -15480, -15652, -15824, -15996, -16168, -16340, -16512, -16684, - -16856, -17028, -17200, -17372, -17544, -17716, -17888, -18060, -18232, - -18404, -18576, -18748, -18920, -19092, -19264, -19436, -19608, -19780, - -19952, -20124, -20296, -20468, -20640, -20812, -20984, -21156, -21328, - -21500, -21672, -21844, -22016, -22188, -22360, -22532, -22704, -22876, - -23048, -23220, -23392, -23564, -23736, -23908, -24080, -24252, -24424, - -24596, -24768, -24940, -25112, -25284, -25456, -25628, -25800, -25972, - -26144, -26316, -26488, -26660, -26832, -27004, -27176, -27348, -27520, - -27692, -27864, -28036, -28208, -28380, -28552, -28724, -28896, -29068, - -29240, -29412, -29584, -29756, -29928, -30100, -30272, -30444, -30616, - -30788, -30960, -31132, -31304, -31476, -31648, -31820, -31992, -32164, - -32336, -32508, -32680, -32852, -33024, -33196, -33368, -33540, -33712, - -33884, -34056, -34228, -34400, -34572, -34744, -34916, -35088, -35260, - -35432, -35604, -35776, -35948, -36120, -36292, -36464, -36636, -36808, - -36980, -37152, -37324, -37496, -37668, -37840, -38012, -38184, -38356, - -38528, -38700, -38872, -39044, -39216, -39388, -39560, -39732, -39904, - -40076, -40248, -40420, -40592, -40764, -40936, -41108, -41280, -41452, - -41624, -41796, -41968, -42140, -42312, -42484, -42656, -42828, -43000, - -43172, -43344, -43516, -43688, -43860 - }; - - private static readonly int[] Cb1Lut = - { - 0, 339, 678, 1017, 1356, 1695, 2034, 2373, 2712, 3051, 3390, 3729, 4068, - 4407, 4746, 5085, 5424, 5763, 6102, 6441, 6780, 7119, 7458, 7797, 8136, - 8475, 8814, 9153, 9492, 9831, 10170, 10509, 10848, 11187, 11526, 11865, - 12204, 12543, 12882, 13221, 13560, 13899, 14238, 14577, 14916, 15255, - 15594, 15933, 16272, 16611, 16950, 17289, 17628, 17967, 18306, 18645, - 18984, 19323, 19662, 20001, 20340, 20679, 21018, 21357, 21696, 22035, - 22374, 22713, 23052, 23391, 23730, 24069, 24408, 24747, 25086, 25425, - 25764, 26103, 26442, 26781, 27120, 27459, 27798, 28137, 28476, 28815, - 29154, 29493, 29832, 30171, 30510, 30849, 31188, 31527, 31866, 32205, - 32544, 32883, 33222, 33561, 33900, 34239, 34578, 34917, 35256, 35595, - 35934, 36273, 36612, 36951, 37290, 37629, 37968, 38307, 38646, 38985, - 39324, 39663, 40002, 40341, 40680, 41019, 41358, 41697, 42036, 42375, - 42714, 43053, 43392, 43731, 44070, 44409, 44748, 45087, 45426, 45765, - 46104, 46443, 46782, 47121, 47460, 47799, 48138, 48477, 48816, 49155, - 49494, 49833, 50172, 50511, 50850, 51189, 51528, 51867, 52206, 52545, - 52884, 53223, 53562, 53901, 54240, 54579, 54918, 55257, 55596, 55935, - 56274, 56613, 56952, 57291, 57630, 57969, 58308, 58647, 58986, 59325, - 59664, 60003, 60342, 60681, 61020, 61359, 61698, 62037, 62376, 62715, - 63054, 63393, 63732, 64071, 64410, 64749, 65088, 65427, 65766, 66105, - 66444, 66783, 67122, 67461, 67800, 68139, 68478, 68817, 69156, 69495, - 69834, 70173, 70512, 70851, 71190, 71529, 71868, 72207, 72546, 72885, - 73224, 73563, 73902, 74241, 74580, 74919, 75258, 75597, 75936, 76275, - 76614, 76953, 77292, 77631, 77970, 78309, 78648, 78987, 79326, 79665, - 80004, 80343, 80682, 81021, 81360, 81699, 82038, 82377, 82716, 83055, - 83394, 83733, 84072, 84411, 84750, 85089, 85428, 85767, 86106, 86445 - }; - - private static readonly int[] Cb2Cr0Lut = - { - 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, - 6656, 7168, 7680, 8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776, - 12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872, 16384, 16896, - 17408, 17920, 18432, 18944, 19456, 19968, 20480, 20992, 21504, 22016, - 22528, 23040, 23552, 24064, 24576, 25088, 25600, 26112, 26624, 27136, - 27648, 28160, 28672, 29184, 29696, 30208, 30720, 31232, 31744, 32256, - 32768, 33280, 33792, 34304, 34816, 35328, 35840, 36352, 36864, 37376, - 37888, 38400, 38912, 39424, 39936, 40448, 40960, 41472, 41984, 42496, - 43008, 43520, 44032, 44544, 45056, 45568, 46080, 46592, 47104, 47616, - 48128, 48640, 49152, 49664, 50176, 50688, 51200, 51712, 52224, 52736, - 53248, 53760, 54272, 54784, 55296, 55808, 56320, 56832, 57344, 57856, - 58368, 58880, 59392, 59904, 60416, 60928, 61440, 61952, 62464, 62976, - 63488, 64000, 64512, 65024, 65536, 66048, 66560, 67072, 67584, 68096, - 68608, 69120, 69632, 70144, 70656, 71168, 71680, 72192, 72704, 73216, - 73728, 74240, 74752, 75264, 75776, 76288, 76800, 77312, 77824, 78336, - 78848, 79360, 79872, 80384, 80896, 81408, 81920, 82432, 82944, 83456, - 83968, 84480, 84992, 85504, 86016, 86528, 87040, 87552, 88064, 88576, - 89088, 89600, 90112, 90624, 91136, 91648, 92160, 92672, 93184, 93696, - 94208, 94720, 95232, 95744, 96256, 96768, 97280, 97792, 98304, 98816, - 99328, 99840, 100352, 100864, 101376, 101888, 102400, 102912, 103424, - 103936, 104448, 104960, 105472, 105984, 106496, 107008, 107520, 108032, - 108544, 109056, 109568, 110080, 110592, 111104, 111616, 112128, 112640, - 113152, 113664, 114176, 114688, 115200, 115712, 116224, 116736, 117248, - 117760, 118272, 118784, 119296, 119808, 120320, 120832, 121344, 121856, - 122368, 122880, 123392, 123904, 124416, 124928, 125440, 125952, 126464, - 126976, 127488, 128000, 128512, 129024, 129536, 130048, 130560 - }; - - private static readonly int[] Cr1Lut = - { - 0, 429, 858, 1287, 1716, 2145, 2574, 3003, 3432, 3861, 4290, 4719, 5148, - 5577, 6006, 6435, 6864, 7293, 7722, 8151, 8580, 9009, 9438, 9867, 10296, - 10725, 11154, 11583, 12012, 12441, 12870, 13299, 13728, 14157, 14586, - 15015, 15444, 15873, 16302, 16731, 17160, 17589, 18018, 18447, 18876, - 19305, 19734, 20163, 20592, 21021, 21450, 21879, 22308, 22737, 23166, - 23595, 24024, 24453, 24882, 25311, 25740, 26169, 26598, 27027, 27456, - 27885, 28314, 28743, 29172, 29601, 30030, 30459, 30888, 31317, 31746, - 32175, 32604, 33033, 33462, 33891, 34320, 34749, 35178, 35607, 36036, - 36465, 36894, 37323, 37752, 38181, 38610, 39039, 39468, 39897, 40326, - 40755, 41184, 41613, 42042, 42471, 42900, 43329, 43758, 44187, 44616, - 45045, 45474, 45903, 46332, 46761, 47190, 47619, 48048, 48477, 48906, - 49335, 49764, 50193, 50622, 51051, 51480, 51909, 52338, 52767, 53196, - 53625, 54054, 54483, 54912, 55341, 55770, 56199, 56628, 57057, 57486, - 57915, 58344, 58773, 59202, 59631, 60060, 60489, 60918, 61347, 61776, - 62205, 62634, 63063, 63492, 63921, 64350, 64779, 65208, 65637, 66066, - 66495, 66924, 67353, 67782, 68211, 68640, 69069, 69498, 69927, 70356, - 70785, 71214, 71643, 72072, 72501, 72930, 73359, 73788, 74217, 74646, - 75075, 75504, 75933, 76362, 76791, 77220, 77649, 78078, 78507, 78936, - 79365, 79794, 80223, 80652, 81081, 81510, 81939, 82368, 82797, 83226, - 83655, 84084, 84513, 84942, 85371, 85800, 86229, 86658, 87087, 87516, - 87945, 88374, 88803, 89232, 89661, 90090, 90519, 90948, 91377, 91806, - 92235, 92664, 93093, 93522, 93951, 94380, 94809, 95238, 95667, 96096, - 96525, 96954, 97383, 97812, 98241, 98670, 99099, 99528, 99957, 100386, - 100815, 101244, 101673, 102102, 102531, 102960, 103389, 103818, 104247, - 104676, 105105, 105534, 105963, 106392, 106821, 107250, 107679, 108108, - 108537, 108966, 109395 - }; - - private static readonly int[] Cr2Lut = - { - 0, 83, 166, 249, 332, 415, 498, 581, 664, 747, 830, 913, 996, 1079, 1162, - 1245, 1328, 1411, 1494, 1577, 1660, 1743, 1826, 1909, 1992, 2075, 2158, - 2241, 2324, 2407, 2490, 2573, 2656, 2739, 2822, 2905, 2988, 3071, 3154, - 3237, 3320, 3403, 3486, 3569, 3652, 3735, 3818, 3901, 3984, 4067, 4150, - 4233, 4316, 4399, 4482, 4565, 4648, 4731, 4814, 4897, 4980, 5063, 5146, - 5229, 5312, 5395, 5478, 5561, 5644, 5727, 5810, 5893, 5976, 6059, 6142, - 6225, 6308, 6391, 6474, 6557, 6640, 6723, 6806, 6889, 6972, 7055, 7138, - 7221, 7304, 7387, 7470, 7553, 7636, 7719, 7802, 7885, 7968, 8051, 8134, - 8217, 8300, 8383, 8466, 8549, 8632, 8715, 8798, 8881, 8964, 9047, 9130, - 9213, 9296, 9379, 9462, 9545, 9628, 9711, 9794, 9877, 9960, 10043, 10126, - 10209, 10292, 10375, 10458, 10541, 10624, 10707, 10790, 10873, 10956, - 11039, 11122, 11205, 11288, 11371, 11454, 11537, 11620, 11703, 11786, - 11869, 11952, 12035, 12118, 12201, 12284, 12367, 12450, 12533, 12616, - 12699, 12782, 12865, 12948, 13031, 13114, 13197, 13280, 13363, 13446, - 13529, 13612, 13695, 13778, 13861, 13944, 14027, 14110, 14193, 14276, - 14359, 14442, 14525, 14608, 14691, 14774, 14857, 14940, 15023, 15106, - 15189, 15272, 15355, 15438, 15521, 15604, 15687, 15770, 15853, 15936, - 16019, 16102, 16185, 16268, 16351, 16434, 16517, 16600, 16683, 16766, - 16849, 16932, 17015, 17098, 17181, 17264, 17347, 17430, 17513, 17596, - 17679, 17762, 17845, 17928, 18011, 18094, 18177, 18260, 18343, 18426, - 18509, 18592, 18675, 18758, 18841, 18924, 19007, 19090, 19173, 19256, - 19339, 19422, 19505, 19588, 19671, 19754, 19837, 19920, 20003, 20086, - 20169, 20252, 20335, 20418, 20501, 20584, 20667, 20750, 20833, 20916, - 20999, 21082, 21165 - }; - [Benchmark(Baseline = true, Description = "Floating Point Conversion")] public Vector3 RgbaToYcbCr() { @@ -297,9 +71,9 @@ int g = 255; int b = 255; - float yy = (Y0Lut[r] + Y1Lut[g] + Y2Lut[b]) >> 10; - float cb = 128 + ((Cb0Lut[r] - Cb1Lut[g] + Cb2Cr0Lut[b]) >> 10); - float cr = 128 + ((Cb2Cr0Lut[r] - Cr1Lut[g] - Cr2Lut[b]) >> 10); + float yy = (LookupTables.Y0[r] + LookupTables.Y1[g] + LookupTables.Y2[b]) >> 10; + float cb = 128 + ((LookupTables.Cb0[r] - LookupTables.Cb1[g] + LookupTables.Cb2Cr0[b]) >> 10); + float cr = 128 + ((LookupTables.Cb2Cr0[r] - LookupTables.Cr1[g] - LookupTables.Cr2[b]) >> 10); return new Vector3(yy, cb, cr); } From 65fb6395be1ae7479733ccdd10eae708a9230c0f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 12 Jan 2017 05:01:11 +0100 Subject: [PATCH 02/19] refactored RgbaToYcbCr benchmarks to operate on arrays + added Vector based experiments --- .../ImageSharp.Benchmarks/Color/RgbToYCbCr.cs | 379 ++++++++++++++++-- 1 file changed, 337 insertions(+), 42 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs index 33bc85da0..0c777b86b 100644 --- a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs +++ b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs @@ -1,81 +1,376 @@ namespace ImageSharp.Benchmarks { + using System; + using System.Buffers; using System.Numerics; + using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; + using ImageSharp.Formats.Jpg; + public partial class RgbToYCbCr { + private const int InputColorCount = 64; + + private const int InputByteCount = InputColorCount * 3; + private static readonly Vector3 VectorY = new Vector3(0.299F, 0.587F, 0.114F); + private static readonly Vector3 VectorCb = new Vector3(-0.168736F, 0.331264F, 0.5F); + private static readonly Vector3 VectorCr = new Vector3(0.5F, 0.418688F, 0.081312F); + private static class ScaledCoeffs + { + public static readonly int[] Y = + { + 306, 601, 117, 0, + 306, 601, 117, 0, + }; + + public static readonly int[] Cb = + { + -172, 339, 512, 0, + -172, 339, 512, 0, + }; + + public static readonly int[] Cr = + { + 512, 429, 83, 0, + 512, 429, 83, 0, + }; + + public static class SelectLeft + { + public static readonly int[] Y = + { + 1, 1, 1, 0, + 0, 0, 0, 0, + }; + + public static readonly int[] Cb = + { + 1, -1, 1, 0, + 0, 0, 0, 0, + }; + + public static readonly int[] Cr = + { + 1, -1, -1, 0, + 0, 0, 0, 0, + }; + } + + public static class SelectRight + { + public static readonly int[] Y = + { + 0, 0, 0, 0, + 1, 1, 1, 0, + }; + + public static readonly int[] Cb = + { + 0, 0, 0, 0, + 1, -1, 1, 0, + }; + + public static readonly int[] Cr = + { + 0, 0, 0, 0, + 1, -1, -1, 0, + }; + } + } + + // Waiting for C# 7 stackalloc keyword patiently ... + private static class OnStackInputCache + { + public unsafe struct Byte + { + public fixed byte Data[InputByteCount * 3]; + + public static Byte Create(byte[] data) + { + Byte result = default(Byte); + for (int i = 0; i < data.Length; i++) + { + result.Data[i] = data[i]; + } + return result; + } + } + } + + public struct Result + { + internal Block8x8F Y; + internal Block8x8F Cb; + internal Block8x8F Cr; + } + + // The operation is defined as "RGBA -> YCbCr Transform a stream of bytes into a stream of floats" + // We need to benchmark the whole operation, to get true results, not missing any side effects! + private byte[] inputSourceRGB = null; + + private int[] inputSourceRGBAsInteger = null; + + [Setup] + public void Setup() + { + // Console.WriteLine("Vector.Count: " + Vector.Count); + this.inputSourceRGB = new byte[InputByteCount]; + for (int i = 0; i < this.inputSourceRGB.Length; i++) + { + this.inputSourceRGB[i] = (byte)(42 + i); + } + this.inputSourceRGBAsInteger = new int[InputByteCount + Vector.Count]; // Filling this should be part of the measured operation + } + [Benchmark(Baseline = true, Description = "Floating Point Conversion")] - public Vector3 RgbaToYcbCr() + public unsafe void RgbaToYcbCrScalarFloat() { - Vector3 v = new Vector3(255); + // Copy the input to the stack: + OnStackInputCache.Byte input = OnStackInputCache.Byte.Create(this.inputSourceRGB); - float yy = (0.299F * v.X) + (0.587F * v.Y) + (0.114F * v.Z); - float cb = 128 + ((-0.168736F * v.X) - (0.331264F * v.Y) + (0.5F * v.Z)); - float cr = 128 + ((0.5F * v.X) - (0.418688F * v.Y) - (0.081312F * v.Z)); + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) - return new Vector3(yy, cb, cr); + for (int i = 0; i < InputColorCount; i++) + { + int i3 = i * 3; + float r = input.Data[i3 + 0]; + float g = input.Data[i3 + 1]; + float b = input.Data[i3 + 2]; + + *yPtr++ = (0.299F * r) + (0.587F * g) + (0.114F * b); + *cbPtr++ = 128 + ((-0.168736F * r) - (0.331264F * g) + (0.5F * b)); + *crPtr++ = 128 + ((0.5F * r) - (0.418688F * g) - (0.081312F * b)); + } } [Benchmark(Description = "Simd Floating Point Conversion")] - public Vector3 RgbaToYcbCrSimd() + public unsafe void RgbaToYcbCrSimdFloat() { - Vector3 vectorRgb = new Vector3(255); - Vector3 vectorY = VectorY * vectorRgb; - Vector3 vectorCb = VectorCb * vectorRgb; - Vector3 vectorCr = VectorCr * vectorRgb; + // Copy the input to the stack: + OnStackInputCache.Byte input = OnStackInputCache.Byte.Create(this.inputSourceRGB); + + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) + + for (int i = 0; i < InputColorCount; i++) + { + int i3 = i * 3; - float yy = vectorY.X + vectorY.Y + vectorY.Z; - float cb = 128 + (vectorCb.X - vectorCb.Y + vectorCb.Z); - float cr = 128 + (vectorCr.X - vectorCr.Y - vectorCr.Z); + Vector3 vectorRgb = new Vector3( + input.Data[i3 + 0], + input.Data[i3 + 1], + input.Data[i3 + 2] + ); - return new Vector3(yy, cb, cr); + Vector3 vectorY = VectorY * vectorRgb; + Vector3 vectorCb = VectorCb * vectorRgb; + Vector3 vectorCr = VectorCr * vectorRgb; + + // Should be better in theory, but came out to be worse: :( + // Vector3 c = new Vector3(0, 128, 128); + // Vector3 xx = new Vector3(vectorY.X, vectorCb.X, vectorCr.X); + // Vector3 yy = new Vector3(vectorY.Y, -vectorCb.Y, -vectorCr.Y); + // Vector3 zz = new Vector3(vectorY.Z, vectorCb.Z, -vectorCr.Z); + + // c += xx + yy + zz; + // *yPtr++ = c.X; + // *cbPtr++ = c.Y; + // *crPtr++ = c.Z; + + *yPtr++ = vectorY.X + vectorY.Y + vectorY.Z; + *cbPtr++ = 128 + (vectorCb.X - vectorCb.Y + vectorCb.Z); + *crPtr++ = 128 + (vectorCr.X - vectorCr.Y - vectorCr.Z); + } } - [Benchmark(Description = "Scaled Integer Conversion")] - public Vector3 RgbaToYcbCrScaled() + [Benchmark(Description = "Scaled Integer Conversion + Vector")] + public unsafe void RgbaToYcbCrScaledIntegerSimd() + { + // Copy the input to the stack: + + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) + + Vector yCoeffs = new Vector(ScaledCoeffs.Y); + Vector cbCoeffs = new Vector(ScaledCoeffs.Cb); + Vector crCoeffs = new Vector(ScaledCoeffs.Cr); + + for (int i = 0; i < this.inputSourceRGB.Length; i++) + { + this.inputSourceRGBAsInteger[i] = this.inputSourceRGB[i]; + } + + for (int i = 0; i < InputColorCount; i += 2) + { + Vector rgb = new Vector(this.inputSourceRGBAsInteger, i * 3); + + Vector y = yCoeffs * rgb; + Vector cb = cbCoeffs * rgb; + Vector cr = crCoeffs * rgb; + + *yPtr++ = (y[0] + y[1] + y[2]) >> 10; + *cbPtr++ = 128 + ((cb[0] - cb[1] + cb[2]) >> 10); + *crPtr++ = 128 + ((cr[0] - cr[1] - cr[2]) >> 10); + + *yPtr++ = (y[4] + y[5] + y[6]) >> 10; + *cbPtr++ = 128 + ((cb[4] - cb[5] + cb[6]) >> 10); + *crPtr++ = 128 + ((cr[4] - cr[5] - cr[6]) >> 10); + } + } + + /// + /// This should perform better. Coreclr emmitted Vector.Dot() code lacks the vectorization even with IsHardwareAccelerated == true. + /// Kept this benchmark because maybe it will be improved in a future CLR release. + /// + /// https://www.gamedev.net/topic/673396-c-systemnumericsvectors-slow/ + /// + /// + [Benchmark(Description = "Scaled Integer Conversion + Vector + Dot Product")] + public unsafe void RgbaToYcbCrScaledIntegerSimdWithDotProduct() { - int r = 255; - int g = 255; - int b = 255; + // Copy the input to the stack: + + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) + + Vector yCoeffs = new Vector(ScaledCoeffs.Y); + Vector cbCoeffs = new Vector(ScaledCoeffs.Cb); + Vector crCoeffs = new Vector(ScaledCoeffs.Cr); + + Vector leftY = new Vector(ScaledCoeffs.SelectLeft.Y); + Vector leftCb = new Vector(ScaledCoeffs.SelectLeft.Cb); + Vector leftCr = new Vector(ScaledCoeffs.SelectLeft.Cr); - // Scale by 1024, add .5F and truncate value - int y0 = 306 * r; // (0.299F * 1024) + .5F - int y1 = 601 * g; // (0.587F * 1024) + .5F - int y2 = 117 * b; // (0.114F * 1024) + .5F + Vector rightY = new Vector(ScaledCoeffs.SelectRight.Y); + Vector rightCb = new Vector(ScaledCoeffs.SelectRight.Cb); + Vector rightCr = new Vector(ScaledCoeffs.SelectRight.Cr); - int cb0 = -172 * r; // (-0.168736F * 1024) + .5F - int cb1 = 339 * g; // (0.331264F * 1024) + .5F - int cb2 = 512 * b; // (0.5F * 1024) + .5F + for (int i = 0; i < this.inputSourceRGB.Length; i++) + { + this.inputSourceRGBAsInteger[i] = this.inputSourceRGB[i]; + } - int cr0 = 512 * r; // (0.5F * 1024) + .5F - int cr1 = 429 * g; // (0.418688F * 1024) + .5F - int cr2 = 83 * b; // (0.081312F * 1024) + .5F + for (int i = 0; i < InputColorCount; i += 2) + { + Vector rgb = new Vector(this.inputSourceRGBAsInteger, i * 3); - float yy = (y0 + y1 + y2) >> 10; - float cb = 128 + ((cb0 - cb1 + cb2) >> 10); - float cr = 128 + ((cr0 - cr1 - cr2) >> 10); + Vector y = yCoeffs * rgb; + Vector cb = cbCoeffs * rgb; + Vector cr = crCoeffs * rgb; - return new Vector3(yy, cb, cr); + VectorizedConvertImpl(ref yPtr, ref cbPtr, ref crPtr, y, cb, cr, leftY, leftCb, leftCr); + VectorizedConvertImpl(ref yPtr, ref cbPtr, ref crPtr, y, cb, cr, rightY, rightCb, rightCr); + } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe void VectorizedConvertImpl( + ref float* yPtr, + ref float* cbPtr, + ref float* crPtr, + Vector y, + Vector cb, + Vector cr, + Vector yAgg, + Vector cbAgg, + Vector crAgg) + { + int ySum = Vector.Dot(y, yAgg); + int cbSum = Vector.Dot(cb, cbAgg); + int crSum = Vector.Dot(cr, crAgg); + *yPtr++ = ySum >> 10; + *cbPtr++ = 128 + (cbSum >> 10); + *crPtr++ = 128 + (crSum >> 10); + } + + [Benchmark(Description = "Scaled Integer Conversion")] + public unsafe void RgbaToYcbCrScaledInteger() + { + // Copy the input to the stack: + OnStackInputCache.Byte input = OnStackInputCache.Byte.Create(this.inputSourceRGB); + + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) + + for (int i = 0; i < InputColorCount; i++) + { + int i3 = i * 3; + int r = input.Data[i3 + 0]; + int g = input.Data[i3 + 1]; + int b = input.Data[i3 + 2]; + + // Scale by 1024, add .5F and truncate value + int y0 = 306 * r; // (0.299F * 1024) + .5F + int y1 = 601 * g; // (0.587F * 1024) + .5F + int y2 = 117 * b; // (0.114F * 1024) + .5F + + int cb0 = -172 * r; // (-0.168736F * 1024) + .5F + int cb1 = 339 * g; // (0.331264F * 1024) + .5F + int cb2 = 512 * b; // (0.5F * 1024) + .5F + + int cr0 = 512 * r; // (0.5F * 1024) + .5F + int cr1 = 429 * g; // (0.418688F * 1024) + .5F + int cr2 = 83 * b; // (0.081312F * 1024) + .5F + + *yPtr++ = (y0 + y1 + y2) >> 10; + *cbPtr++ = 128 + ((cb0 - cb1 + cb2) >> 10); + *crPtr++ = 128 + ((cr0 - cr1 - cr2) >> 10); + } + } + [Benchmark(Description = "Scaled Integer LUT Conversion")] - public Vector3 RgbaToYcbCrScaledLut() + public unsafe void RgbaToYcbCrScaledIntegerLut() { - int r = 255; - int g = 255; - int b = 255; + // Copy the input to the stack: + OnStackInputCache.Byte input = OnStackInputCache.Byte.Create(this.inputSourceRGB); + + // On-stack output: + Result result = default(Result); + float* yPtr = (float*)&result.Y; + float* cbPtr = (float*)&result.Cb; + float* crPtr = (float*)&result.Cr; + // end of code-bloat block :) + + for (int i = 0; i < InputColorCount; i++) + { + int i3 = i * 3; - float yy = (LookupTables.Y0[r] + LookupTables.Y1[g] + LookupTables.Y2[b]) >> 10; - float cb = 128 + ((LookupTables.Cb0[r] - LookupTables.Cb1[g] + LookupTables.Cb2Cr0[b]) >> 10); - float cr = 128 + ((LookupTables.Cb2Cr0[r] - LookupTables.Cr1[g] - LookupTables.Cr2[b]) >> 10); + int r = input.Data[i3 + 0]; + int g = input.Data[i3 + 1]; + int b = input.Data[i3 + 2]; - return new Vector3(yy, cb, cr); + // TODO: Maybe concatenating all the arrays in LookupTables to a flat one can improve this! + *yPtr++ = (LookupTables.Y0[r] + LookupTables.Y1[g] + LookupTables.Y2[b]) >> 10; + *cbPtr++ = 128 + ((LookupTables.Cb0[r] - LookupTables.Cb1[g] + LookupTables.Cb2Cr0[b]) >> 10); + *crPtr++ = 128 + ((LookupTables.Cb2Cr0[r] - LookupTables.Cr1[g] - LookupTables.Cr2[b]) >> 10); + } } } } \ No newline at end of file From f256120c748e5fd6bbf28f77c90041599bb90831 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2017 17:25:06 +1100 Subject: [PATCH 03/19] Fix concurrent png decoding --- src/ImageSharp.Formats.Png/PngDecoderCore.cs | 38 ++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp.Formats.Png/PngDecoderCore.cs b/src/ImageSharp.Formats.Png/PngDecoderCore.cs index ed5862e07..7ed38b6e8 100644 --- a/src/ImageSharp.Formats.Png/PngDecoderCore.cs +++ b/src/ImageSharp.Formats.Png/PngDecoderCore.cs @@ -129,7 +129,7 @@ namespace ImageSharp.Formats /// Decodes the stream to the image. /// /// The pixel format. - /// The image to decode to. + /// The image to decode to. /// The stream containing image data. /// /// Thrown if the stream does not contain and end chunk. @@ -139,7 +139,7 @@ namespace ImageSharp.Formats /// public void Decode(Image image, Stream stream) where TColor : struct, IPackedPixel, IEquatable - { + { Image currentImage = image; this.currentStream = stream; this.currentStream.Skip(8); @@ -259,11 +259,11 @@ namespace ImageSharp.Formats /// Reads the data chunk containing physical dimension data. /// /// The pixel format. - /// The image to read to. + /// The image to read to. /// The data containing physical data. private void ReadPhysicalChunk(Image image, byte[] data) where TColor : struct, IPackedPixel, IEquatable - { + { data.ReverseBytes(0, 4); data.ReverseBytes(4, 4); @@ -322,11 +322,11 @@ namespace ImageSharp.Formats /// Reads the scanlines within the image. /// /// The pixel format. - /// The containing data. + /// The containing data. /// The pixel data. private void ReadScanlines(MemoryStream dataStream, PixelAccessor pixels) where TColor : struct, IPackedPixel, IEquatable - { + { this.bytesPerPixel = this.CalculateBytesPerPixel(); this.bytesPerScanline = this.CalculateScanlineLength(this.header.Width) + 1; this.bytesPerSample = 1; @@ -353,15 +353,16 @@ namespace ImageSharp.Formats /// Decodes the raw pixel data row by row /// /// The pixel format. - /// The compressed pixel data stream. + /// The compressed pixel data stream. /// The image pixel accessor. private void DecodePixelData(Stream compressedStream, PixelAccessor pixels) where TColor : struct, IPackedPixel, IEquatable - { + { byte[] previousScanline = ArrayPool.Shared.Rent(this.bytesPerScanline); byte[] scanline = ArrayPool.Shared.Rent(this.bytesPerScanline); - // Zero out the previousScanline, because the bytes that are rented from the arraypool may not be zero. + // Zero out the scanlines, because the bytes that are rented from the arraypool may not be zero. + Array.Clear(scanline, 0, this.bytesPerScanline); Array.Clear(previousScanline, 0, this.bytesPerScanline); try @@ -425,11 +426,11 @@ namespace ImageSharp.Formats /// /// /// The pixel format. - /// The compressed pixel data stream. + /// The compressed pixel data stream. /// The image pixel accessor. private void DecodeInterlacedPixelData(Stream compressedStream, PixelAccessor pixels) where TColor : struct, IPackedPixel, IEquatable - { + { byte[] previousScanline = ArrayPool.Shared.Rent(this.bytesPerScanline); byte[] scanline = ArrayPool.Shared.Rent(this.bytesPerScanline); @@ -437,7 +438,8 @@ namespace ImageSharp.Formats { for (int pass = 0; pass < 7; pass++) { - // Zero out the previousScanline, because the bytes that are rented from the arraypool may not be zero. + // Zero out the scanlines, because the bytes that are rented from the arraypool may not be zero. + Array.Clear(scanline, 0, this.bytesPerScanline); Array.Clear(previousScanline, 0, this.bytesPerScanline); int y = Adam7FirstRow[pass]; @@ -512,12 +514,12 @@ namespace ImageSharp.Formats /// Processes the de-filtered scanline filling the image pixel data /// /// The pixel format. - /// The de-filtered scanline + /// The de-filtered scanline /// The current image row. /// The image pixels private void ProcessDefilteredScanline(byte[] defilteredScanline, int row, PixelAccessor pixels) where TColor : struct, IPackedPixel, IEquatable - { + { TColor color = default(TColor); switch (this.PngColorType) { @@ -635,14 +637,14 @@ namespace ImageSharp.Formats /// Processes the interlaced de-filtered scanline filling the image pixel data /// /// The pixel format. - /// The de-filtered scanline + /// The de-filtered scanline /// The current image row. /// The image pixels /// The column start index. Always 0 for none interlaced images. /// The column increment. Always 1 for none interlaced images. private void ProcessInterlacedDefilteredScanline(byte[] defilteredScanline, int row, PixelAccessor pixels, int pixelOffset = 0, int increment = 1) where TColor : struct, IPackedPixel, IEquatable - { + { TColor color = default(TColor); switch (this.PngColorType) @@ -755,12 +757,12 @@ namespace ImageSharp.Formats /// Reads a text chunk containing image properties from the data. /// /// The pixel format. - /// The image to decode to. + /// The image to decode to. /// The containing data. /// The maximum length to read. private void ReadTextChunk(Image image, byte[] data, int length) where TColor : struct, IPackedPixel, IEquatable - { + { int zeroIndex = 0; for (int i = 0; i < length; i++) From 62000bfc9f86c06d83b92766bedd03add85b714a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 12 Jan 2017 17:25:45 +1100 Subject: [PATCH 04/19] Add interlace powerpoint image touch #76 [skip ci] --- tests/ImageSharp.Tests/FileTestBase.cs | 1 + tests/ImageSharp.Tests/TestImages.cs | 1 + tests/ImageSharp.Tests/TestImages/Formats/Png/pp.png | 3 +++ 3 files changed, 5 insertions(+) create mode 100644 tests/ImageSharp.Tests/TestImages/Formats/Png/pp.png diff --git a/tests/ImageSharp.Tests/FileTestBase.cs b/tests/ImageSharp.Tests/FileTestBase.cs index 72a681a55..e9343b20d 100644 --- a/tests/ImageSharp.Tests/FileTestBase.cs +++ b/tests/ImageSharp.Tests/FileTestBase.cs @@ -33,6 +33,7 @@ namespace ImageSharp.Tests // TestFile.Create(TestImages.Png.Blur), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Indexed), // Perf: Enable for local testing only TestFile.Create(TestImages.Png.Splash), + TestFile.Create(TestImages.Png.Powerpoint), // TestFile.Create(TestImages.Png.SplashInterlaced), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Interlaced), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Filter0), // Perf: Enable for local testing only diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 7265e45a4..0ce8fb05a 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -19,6 +19,7 @@ namespace ImageSharp.Tests public const string Blur = "Png/blur.png"; public const string Indexed = "Png/indexed.png"; public const string Splash = "Png/splash.png"; + public const string Powerpoint = "Png/pp.png"; public const string SplashInterlaced = "Png/splash-interlaced.png"; diff --git a/tests/ImageSharp.Tests/TestImages/Formats/Png/pp.png b/tests/ImageSharp.Tests/TestImages/Formats/Png/pp.png new file mode 100644 index 000000000..f13accaee --- /dev/null +++ b/tests/ImageSharp.Tests/TestImages/Formats/Png/pp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99879d99fa8589427023012a0388ab0380b6d30b54921e2b7a39f43ae4b1bcc3 +size 12867 From 7e7ab76aba9fb4ba6b5683eaab5c264d1e42e5c5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 14 Jan 2017 19:39:22 +0100 Subject: [PATCH 05/19] branch-creation test commit --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 7346bdc28..6da79b611 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "projects": [ "src" ], "sdk": { - "version": "1.0.0-preview2-003121" + "version": "1.0.0-preview2-003131" } } \ No newline at end of file From be894cc0302d2fdaaa8c6582ec2a68d8cdae1f40 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 14 Jan 2017 22:08:03 +0100 Subject: [PATCH 06/19] Initialized ImageSharp.Sandbox46.csproj --- ImageSharp.sln | 7 ++ .../ImageSharp.Sandbox46.csproj | 99 +++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++++ tests/ImageSharp.Sandbox46/Sandbox.cs | 20 ++++ tests/ImageSharp.Sandbox46/packages.config | 9 ++ 5 files changed, 171 insertions(+) create mode 100644 tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj create mode 100644 tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs create mode 100644 tests/ImageSharp.Sandbox46/Sandbox.cs create mode 100644 tests/ImageSharp.Sandbox46/packages.config diff --git a/ImageSharp.sln b/ImageSharp.sln index 1f848b34d..5490c1048 100644 --- a/ImageSharp.sln +++ b/ImageSharp.sln @@ -53,6 +53,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A src\Shared\stylecop.json = src\Shared\stylecop.json EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Sandbox46", "tests\ImageSharp.Sandbox46\ImageSharp.Sandbox46.csproj", "{96188137-5FA6-4924-AB6E-4EFF79C6E0BB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -99,6 +101,10 @@ Global {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Debug|Any CPU.Build.0 = Debug|Any CPU {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Release|Any CPU.ActiveCfg = Release|Any CPU {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Release|Any CPU.Build.0 = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -115,5 +121,6 @@ Global {556ABDCF-ED93-4327-BE98-F6815F78B9B8} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} {A623CFE9-9D2B-4528-AD1F-2E834B061134} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} {9E574A07-F879-4811-9C41-5CBDC6BAFDB7} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} EndGlobalSection EndGlobal diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj new file mode 100644 index 000000000..452eaca43 --- /dev/null +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -0,0 +1,99 @@ + + + + + Debug + AnyCPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB} + Library + Properties + ImageSharp + ImageSharp.Sandbox46 + v4.6.1 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + ..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll + True + + + ..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll + True + + + ..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\net45\xunit.core.dll + True + + + ..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\net45\xunit.execution.desktop.dll + True + + + + + ..\..\src\ImageSharp\bin\$(Configuration)\net45\ImageSharp.dll + + + ..\..\src\ImageSharp.Drawing\bin\$(Configuration)\net45\ImageSharp.Drawing.dll + + + ..\..\src\ImageSharp.Formats.Bmp\bin\$(Configuration)\net45\ImageSharp.Formats.Bmp.dll + + + ..\..\src\ImageSharp.Formats.Gif\bin\$(Configuration)\net45\ImageSharp.Formats.Gif.dll + + + ..\..\src\ImageSharp.Formats.Jpeg\bin\$(Configuration)\net45\ImageSharp.Formats.Jpeg.dll + + + ..\..\src\ImageSharp.Formats.Png\bin\$(Configuration)\net45\ImageSharp.Formats.Png.dll + + + ..\..\src\ImageSharp\bin\$(Configuration)\net45\ImageSharp.Processing.dll + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs b/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..bee8fb408 --- /dev/null +++ b/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ImageSharp.Sandbox46")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Sapa")] +[assembly: AssemblyProduct("ImageSharp.Sandbox46")] +[assembly: AssemblyCopyright("Copyright © Sapa 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("96188137-5fa6-4924-ab6e-4eff79c6e0bb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/ImageSharp.Sandbox46/Sandbox.cs b/tests/ImageSharp.Sandbox46/Sandbox.cs new file mode 100644 index 000000000..a92bb342e --- /dev/null +++ b/tests/ImageSharp.Sandbox46/Sandbox.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ImageSharp +{ + using Xunit; + + public class Sandbox + { + [Fact] + public void HelloImage() + { + Image img = new Image(10, 20); + Assert.Equal(10, img.Width); + } + } +} diff --git a/tests/ImageSharp.Sandbox46/packages.config b/tests/ImageSharp.Sandbox46/packages.config new file mode 100644 index 000000000..128826db5 --- /dev/null +++ b/tests/ImageSharp.Sandbox46/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file From 3c2f64d68139bd445a8e24c1b41fa5073fb22251 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 14 Jan 2017 22:37:17 +0100 Subject: [PATCH 07/19] Test code cleanup: removed EnumHelper, moved MeasureFixture to TestUtilities, Jpeg test formatting --- .../Formats/Jpg/Block8x8FTests.cs | 4 +- ...tilityTestClassBase.cs => JpegTestBase.cs} | 39 ++------------- .../Formats/Jpg/ReferenceImplementations.cs | 14 +++--- .../Jpg/ReferenceImplementationsTests.cs | 16 +++--- .../TestUtilities/EnumHelper.cs | 19 ------- .../TestUtilities/MeasureFixture.cs | 50 +++++++++++++++++++ .../TestUtilities/TestUtilityExtensions.cs | 8 ++- .../Tests/TestUtilityExtensionsTests.cs | 6 +-- 8 files changed, 80 insertions(+), 76 deletions(-) rename tests/ImageSharp.Tests/Formats/Jpg/{UtilityTestClassBase.cs => JpegTestBase.cs} (75%) delete mode 100644 tests/ImageSharp.Tests/TestUtilities/EnumHelper.cs create mode 100644 tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index 6736548e6..1f055bab4 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -12,14 +12,12 @@ namespace ImageSharp.Tests { using System.Diagnostics; using System.Numerics; - - using ImageSharp.Formats; using ImageSharp.Formats.Jpg; using Xunit; using Xunit.Abstractions; - public class Block8x8FTests : UtilityTestClassBase + public class Block8x8FTests : JpegTestBase { #if BENCHMARKING public const int Times = 1000000; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/UtilityTestClassBase.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegTestBase.cs similarity index 75% rename from tests/ImageSharp.Tests/Formats/Jpg/UtilityTestClassBase.cs rename to tests/ImageSharp.Tests/Formats/Jpg/JpegTestBase.cs index c92c6aa9a..2e568ba34 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/UtilityTestClassBase.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegTestBase.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -13,46 +13,15 @@ namespace ImageSharp.Tests using System; using System.Collections.Generic; using System.Diagnostics; - using System.Runtime.CompilerServices; using ImageSharp.Formats.Jpg; - /// - /// Utility class to measure the execution of an operation. - /// - public class MeasureFixture : TestBase + public class JpegTestBase : MeasureFixture { - protected bool EnablePrinting = true; - - protected void Measure(int times, Action action, [CallerMemberName] string operationName = null) - { - if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} X {times} ..."); - Stopwatch sw = Stopwatch.StartNew(); - - for (int i = 0; i < times; i++) - { - action(); - } - - sw.Stop(); - if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} finished in {sw.ElapsedMilliseconds} ms"); - } - - public MeasureFixture(ITestOutputHelper output) + public JpegTestBase(ITestOutputHelper output) : base(output) { - this.Output = output; } - protected ITestOutputHelper Output { get; } - } - - - public class UtilityTestClassBase : MeasureFixture - { - public UtilityTestClassBase(ITestOutputHelper output) : base(output) - { - } - // ReSharper disable once InconsistentNaming public static float[] Create8x8FloatData() { @@ -66,7 +35,7 @@ namespace ImageSharp.Tests } return result; } - + // ReSharper disable once InconsistentNaming public static int[] Create8x8IntData() { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs index 6aed0d3fa..60c136674 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Tests using ImageSharp.Formats; using ImageSharp.Formats.Jpg; - + /// /// This class contains simplified (unefficient) reference implementations to produce verification data for unit tests /// Floating point DCT code Ported from https://github.com/norishigefukushima/dct_simd @@ -546,8 +546,8 @@ namespace ImageSharp.Tests //y[1] = c0 + c3; y[7] = c0 - c3; /*for(i = 0;i < 8;i++) - { - y[i] *= invsqrt2h; + { + y[i] *= invsqrt2h; }*/ } @@ -643,10 +643,10 @@ namespace ImageSharp.Tests 0: 1.414214 1: 1.387040 2: 1.306563 - 3: + 3: 4: 1.000000 5: 0.785695 - 6: + 6: 7: 0.275899 */ @@ -852,7 +852,7 @@ namespace ImageSharp.Tests bool offsetSourceByNeg128 = false) { MutableSpan sWorker = offsetSourceByNeg128 ? s.AddScalarToAllValues(-128f) : s; - + for (int j = 0; j < 8; j++) { fDCT1Dllm_32f(sWorker.Slice(j * 8), temp.Slice(j * 8)); @@ -866,7 +866,7 @@ namespace ImageSharp.Tests } Transpose8x8(temp, d); - + if (downscaleBy8) { for (int j = 0; j < 64; j++) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs index 66ddeabc0..63878ea34 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Tests.Formats.Jpg using Xunit; using Xunit.Abstractions; - public class ReferenceImplementationsTests : UtilityTestClassBase + public class ReferenceImplementationsTests : JpegTestBase { public ReferenceImplementationsTests(ITestOutputHelper output) : base(output) @@ -31,7 +31,7 @@ namespace ImageSharp.Tests.Formats.Jpg MutableSpan floatSrc = intData.ConvertToFloat32MutableSpan(); ReferenceImplementations.IntegerReferenceDCT.TransformIDCTInplace(intData); - + MutableSpan dest = new MutableSpan(64); MutableSpan temp = new MutableSpan(64); @@ -57,14 +57,14 @@ namespace ImageSharp.Tests.Formats.Jpg var block = original.AddScalarToAllValues(128); ReferenceImplementations.IntegerReferenceDCT.TransformFDCTInplace(block); - + for (int i = 0; i < 64; i++) { block[i] /= 8; } ReferenceImplementations.IntegerReferenceDCT.TransformIDCTInplace(block); - + for (int i = startAt; i < 64; i++) { float expected = original[i]; @@ -93,7 +93,7 @@ namespace ImageSharp.Tests.Formats.Jpg { float expected = data[i]; float actual = (float)src[i]; - + Assert.Equal(expected, actual, new ApproximateFloatComparer(2f)); } } @@ -112,9 +112,9 @@ namespace ImageSharp.Tests.Formats.Jpg { MutableSpan intData = Create8x8RandomIntData(-200, 200, seed); MutableSpan floatSrc = intData.ConvertToFloat32MutableSpan(); - + ReferenceImplementations.IntegerReferenceDCT.TransformFDCTInplace(intData); - + MutableSpan dest = new MutableSpan(64); MutableSpan temp = new MutableSpan(64); @@ -127,6 +127,6 @@ namespace ImageSharp.Tests.Formats.Jpg Assert.Equal(expected, actual, new ApproximateFloatComparer(1f)); } - } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/EnumHelper.cs b/tests/ImageSharp.Tests/TestUtilities/EnumHelper.cs deleted file mode 100644 index 7b6b26e94..000000000 --- a/tests/ImageSharp.Tests/TestUtilities/EnumHelper.cs +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System; - - public class EnumHelper - { - public static T[] GetSortedValues() - { - T[] vals = (T[])Enum.GetValues(typeof(T)); - Array.Sort(vals); - return vals; - } - } -} diff --git a/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs b/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs new file mode 100644 index 000000000..1dadc4884 --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs @@ -0,0 +1,50 @@ +namespace ImageSharp.Tests +{ + using System; + using System.Diagnostics; + using System.Runtime.CompilerServices; + + using Xunit.Abstractions; + + /// + /// Utility class to measure the execution of an operation. It can be used either by inheritance or by composition. + /// + public class MeasureFixture : TestBase + { + /// + /// Value indicating whether priniting is enabled. + /// + protected bool EnablePrinting = true; + + /// + /// Measures and prints the execution time of an , executed multiple times. + /// + /// A value indicating how many times to run the action + /// The to execute + /// The name of the operation to print to the output + public void Measure(int times, Action action, [CallerMemberName] string operationName = null) + { + if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} X {times} ..."); + Stopwatch sw = Stopwatch.StartNew(); + + for (int i = 0; i < times; i++) + { + action(); + } + + sw.Stop(); + if (this.EnablePrinting) this.Output?.WriteLine($"{operationName} finished in {sw.ElapsedMilliseconds} ms"); + } + + /// + /// Initializes a new instance of + /// + /// A instance to print the results + public MeasureFixture(ITestOutputHelper output) + { + this.Output = output; + } + + protected ITestOutputHelper Output { get; } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs index 8b0c65a3c..d2726c16a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs @@ -22,7 +22,7 @@ namespace ImageSharp.Tests private static readonly Dictionary PixelTypes2ClrTypes = new Dictionary(); - private static readonly PixelTypes[] AllConcretePixelTypes = EnumHelper.GetSortedValues() + private static readonly PixelTypes[] AllConcretePixelTypes = GetAllPixelTypes() .Except(new [] {PixelTypes.Undefined, PixelTypes.All }) .ToArray(); @@ -130,5 +130,11 @@ namespace ImageSharp.Tests .Where(pt => pixelTypes.HasFlag(pt)) .Select(pt => new KeyValuePair(pt, pt.ToType())); } + + /// + /// Enumerate all available -s + /// + /// The pixel types + internal static PixelTypes[] GetAllPixelTypes() => (PixelTypes[])Enum.GetValues(typeof(PixelTypes)); } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs index 93d6eab16..23a42c1a6 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs @@ -114,7 +114,7 @@ namespace ImageSharp.Tests IEnumerable> pixelTypesExp) { Assert.Contains(new KeyValuePair(pt, typeof(T)), pixelTypesExp); - + } [Fact] @@ -125,7 +125,7 @@ namespace ImageSharp.Tests var expanded = pixelTypes.ExpandAllTypes(); Assert.Equal(expanded.Count(), 5); - + AssertContainsPixelType(PixelTypes.Alpha8, expanded); AssertContainsPixelType(PixelTypes.Bgr565, expanded); AssertContainsPixelType(PixelTypes.Color, expanded); @@ -138,7 +138,7 @@ namespace ImageSharp.Tests { var expanded = PixelTypes.All.ExpandAllTypes().ToArray(); - Assert.True(expanded.Length >= EnumHelper.GetSortedValues().Length - 2); + Assert.True(expanded.Length >= TestUtilityExtensions.GetAllPixelTypes().Length - 2); AssertContainsPixelType(PixelTypes.Color, expanded); AssertContainsPixelType(PixelTypes.StandardImageClass, expanded); } From 3dae11460f32095b09c3a2b2fb9d2d13e955ebe2 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 14 Jan 2017 22:40:42 +0100 Subject: [PATCH 08/19] added some test files to ImageSharp.Sandbox46.csproj --- .../ImageSharp.Sandbox46.csproj | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index 452eaca43..fd7cc5c78 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -79,6 +79,63 @@ + + Tests\Drawing\BeziersTests.cs + + + Tests\Drawing\DrawImageTest.cs + + + Tests\Drawing\DrawPathTests.cs + + + Tests\Drawing\FillPatternTests.cs + + + Tests\Drawing\FillSolidBrushTests.cs + + + Tests\Drawing\LineComplexPolygonTests.cs + + + Tests\Drawing\LineTests.cs + + + Tests\Drawing\PolygonTests.cs + + + Tests\Drawing\RecolorImageTest.cs + + + Tests\Drawing\SolidBezierTests.cs + + + Tests\Drawing\SolidComplexPolygonTests.cs + + + Tests\Drawing\SolidPolygonTests.cs + + + Tests\Formats\Jpg\Block8x8FTests.cs + + + Tests\Formats\Jpg\JpegTests.cs + + + Tests\Formats\Jpg\ReferenceImplementations.cs + + + Tests\Formats\Jpg\ReferenceImplementationsTests.cs + + + Tests\Formats\Jpg\UtilityTestClassBase.cs + + + Tests\Formats\Jpg\YCbCrImageTests.cs + + + Tests\Processors\Filters\ResizeTests.cs + @@ -86,7 +143,11 @@ - + + + + +