1/* 2cc -Os -o /tmp/gaussblur gaussblur.c -framework ApplicationServices -framework IOKit -Wall 3*/ 4 5#include <CoreFoundation/CoreFoundation.h> 6#include <ApplicationServices/ApplicationServices.h> 7#include <IOKit/graphics/IOGraphicsLib.h> 8#include <stdlib.h> 9#include <stdio.h> 10#include <mach/mach.h> 11#include <mach/mach_time.h> 12 13 14#define DEBG(idx, fmt, args...) \ 15do { \ 16 printf(fmt, ## args); \ 17} while( false ) 18#define bcopy_nc bcopy 19 20#include "../IOGraphicsFamily/bmcompress.h" 21 22 23int main(int argc, char * argv[]) 24{ 25 CGError err; 26 int i, j; 27 CGDisplayCount max; 28 CGDirectDisplayID displayIDs[8]; 29 double scale = 0.0; 30 uint64_t start, end; 31 32 uint32_t * screen; 33 uint32_t rowBytes, bytesPerPixel; 34 uint32_t width, height; 35 uint32_t * buffer; 36 uint32_t * compressBuffer; 37 uint32_t * input; 38 uint32_t * output; 39 uint32_t compressLen; 40 41 { 42 struct mach_timebase_info tbi; 43 kern_return_t r; 44 uint32_t num = 0; 45 uint32_t denom = 0; 46 47 r = mach_timebase_info(&tbi); 48 if (r != KERN_SUCCESS) { 49 abort(); 50 } 51 num = tbi.numer; 52 denom = tbi.denom; 53 54 scale = (double)num / (double)denom; 55 } 56 57 err = CGGetOnlineDisplayList(8, displayIDs, &max); 58 if(err != kCGErrorSuccess) 59 exit(1); 60 if(max > 8) 61 max = 8; 62 63 screen = (uint32_t *) CGDisplayBaseAddress(displayIDs[0]); 64 rowBytes = CGDisplayBytesPerRow(displayIDs[0]); 65 66 printf("Base addr %p, rb %x\n", screen, rowBytes); 67 68 rowBytes >>= 2; 69 70 width = CGDisplayPixelsWide(displayIDs[0]); 71 height = CGDisplayPixelsHigh(displayIDs[0]); 72 73 buffer = malloc(width * height * sizeof(uint32_t)); 74 start = mach_absolute_time(); 75 for (j = 0; j < height; j++) 76 bcopy(screen + j * rowBytes, buffer + j * width, width * sizeof(uint32_t)); 77 end = mach_absolute_time(); 78 79 printf("copy time %f\n", (end - start) * scale / NSEC_PER_SEC); 80 printf("copy Mbs %f\n", ((double) width * height * sizeof(uint32_t)) / 1024.0 / 1024.0 / ((end - start) * scale / NSEC_PER_SEC) ); 81 82 83bytesPerPixel = sizeof(uint32_t); 84 85 compressBuffer = malloc(width * height * sizeof(uint32_t) * 2); 86 87//screen = buffer; 88//rowBytes = width; 89 90 91 start = mach_absolute_time(); 92 compressLen = CompressData( (UInt8 *) screen, bytesPerPixel, 93 width, height, rowBytes << 2, 94 (UInt8 *) compressBuffer, width * height * sizeof(uint32_t) * 2 ); 95 end = mach_absolute_time(); 96 97 printf("compress time %f\n", (end - start) * scale / NSEC_PER_SEC); 98 99 DEBG(thisIndex, " compressed to %d%%\n", (compressLen * 100) / (width * height * sizeof(uint32_t))); 100 101//exit(0); 102 103 uint16_t * sc0 = malloc((width+2) * sizeof(uint16_t)); 104 uint16_t * sc1 = malloc((width+2) * sizeof(uint16_t)); 105 uint16_t * sc2 = malloc((width+2) * sizeof(uint16_t)); 106 uint16_t * sc3 = malloc((width+2) * sizeof(uint16_t)); 107 uint32_t sr0, sr1, sr2, sr3; 108 109 bzero(sc0, (width+2) * sizeof(uint16_t)); 110 bzero(sc1, (width+2) * sizeof(uint16_t)); 111 bzero(sc2, (width+2) * sizeof(uint16_t)); 112 bzero(sc3, (width+2) * sizeof(uint16_t)); 113 114 input = buffer; 115 output = screen; 116 117 start = mach_absolute_time(); 118 for (j = 0; j < height; j++) 119 { 120 for (i = 0; i < width; i++) 121 output[i] = *input++; 122 output += rowBytes; 123 } 124 125 end = mach_absolute_time(); 126 127 printf("time %f\n", (end - start) * scale / NSEC_PER_SEC); 128 129 output = screen; 130 131 uint32_t tmp1, tmp2, out; 132 for (j = 0; j < (height + 2); j++) 133 { 134 input = compressBuffer; 135 if (j < height) 136 input += j; 137 else 138 input += height - 1; 139 input = (uint32_t *)(input[3] + ((uint8_t *)compressBuffer)); 140 141 uint32_t data, repeat, fetch, count = 0; 142 sr0 = sr1 = sr2 = sr3 = 0; 143 144 for (i = 0; i < (width + 2); i++) 145 { 146 if (i < width) 147 { 148 if (!count) 149 { 150 count = *input++; 151 repeat = (count & 0xff000000); 152 count ^= repeat; 153 fetch = true; 154 } 155 else 156 fetch = (0 == repeat); 157 158 count--; 159 160 if (fetch) 161 { 162 data = *input++; 163 164 // grayscale 165 // srgb 13933, 46871, 4732 166 // ntsc 19595, 38470, 7471 167 data = 13933 * (0xff & (data >> 24)) 168 + 46871 * (0xff & (data >> 16)) 169 + 4732 * (0xff & data); 170 data >>= 16; 171 172 // 70% white, 30 % black 173 data *= 19661; 174 data += (103 << 16); 175 data >>= 16; 176 } 177 } 178 179 // gauss blur 180 tmp2 = sr0 + data; 181 sr0 = data; 182 tmp1 = sr1 + tmp2; 183 sr1 = tmp2; 184 tmp2 = sr2 + tmp1; 185 sr2 = tmp1; 186 tmp1 = sr3 + tmp2; 187 sr3 = tmp2; 188 189 tmp2 = sc0[i] + tmp1; 190 sc0[i] = tmp1; 191 tmp1 = sc1[i] + tmp2; 192 sc1[i] = tmp2; 193 tmp2 = sc2[i] + tmp1; 194 sc2[i] = tmp1; 195 out = (128 + sc3[i] + tmp2) >> 8; 196 sc3[i] = tmp2; 197 198 out &= 0xff; 199 if ((i > 1) && (j > 1)) 200 output[i-2] = out | (out << 8) | (out << 16); 201 } 202 203 if (j > 1) 204 output += rowBytes; 205 } 206 207 end = mach_absolute_time(); 208 209 printf("time %f\n", (end - start) * scale / NSEC_PER_SEC); 210 211 exit(0); 212 return(0); 213} 214 215