PageRenderTime 63ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/iphone/ImageWikiApplication.m

https://github.com/anselm/imagewiki
Objective C | 1641 lines | 905 code | 282 blank | 454 comment | 87 complexity | 109210a03ab49e680e2926bdec1d4f14 MD5 | raw file
Possible License(s): GPL-2.0, MIT
  1. /*
  2. This program is free software; you can redistribute it and/or
  3. modify it under the terms of the GNU General Public License
  4. as published by the Free Software Foundation; version 2
  5. of the License.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  13. */
  14. #import <CoreFoundation/CoreFoundation.h>
  15. #import <Foundation/Foundation.h>
  16. #import <GraphicsServices/GraphicsServices.h>
  17. #import <UIKit/UITransformAnimation.h>
  18. #import <UIKit/UIAnimator.h>
  19. //#import <PhotoLibrary/DCFFileGroup.h>
  20. //#import <PhotoLibrary/DCFDirectory.h>
  21. #import "PhotoLibrary.h"
  22. #import "ImageWikiApplication.h"
  23. #include "md5.h"
  24. #include <math.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <dlfcn.h>
  28. #include "jpeg/jinclude.h"
  29. #include "jpeg/jpeglib.h"
  30. #define PREF_FILE @"/var/root/Library/Preferences/org.makerlab.imagewiki.plist"
  31. #define DCIM_PATH @"/private/var/root/Media/DCIM/100APPLE/"
  32. #define TEMP_PATH @"/var/root/Library/imagewiki/"
  33. NSString* POSTDataSeparator = @"---------------------------8f999edae883c6039b244c0d341f45f8";
  34. //int GSEventDeviceOrientation(GSEvent *ev);
  35. CGImageRef CreateCGImageFromData(NSData* data);
  36. static CGColorSpaceRef color_space = 0;
  37. static NSRecursiveLock* lock = 0;
  38. /*
  39. Magic global variables for CoreTelephony.
  40. */
  41. struct CellInfo cellinfo;
  42. int i;
  43. int tl;
  44. /* End magic globals. */
  45. void make_JPEG (char * data, long* length,
  46. int quality, JSAMPLE* image_buffer_bad,
  47. int image_width, int image_height);
  48. int callback(void *connection, CFStringRef string, CFDictionaryRef dictionary, void *data);
  49. void sourcecallback ( CFMachPortRef port, void *msg, CFIndex size, void *info);
  50. void mycallback (void);
  51. @implementation ImageWikiApplication
  52. - (void) applicationSuspend:(struct __GSEvent *) event {
  53. [self setApplicationBadge:[NSString stringWithFormat:@"%d", uploadQSize]];
  54. if( uploadQSize <= 0 && !isCachingNow)
  55. [self terminateWithSuccess];
  56. }
  57. - (void) applicationResume:(struct __GSEvent *) event {
  58. }
  59. - (BOOL) applicationIsReadyToSuspend {
  60. return NO;
  61. }
  62. - (BOOL) suspendRemainInMemory {
  63. return YES;
  64. }
  65. - (void) applicationWillTerminate {
  66. [self removeApplicationBadge];
  67. window = [[UIWindow alloc] initWithContentRect: [UIHardware fullScreenApplicationContentRect] ];
  68. [window release];
  69. }
  70. - (void) didReceiveMemoryWarning {
  71. }
  72. - (void) didReceiveUrgentMemoryWarning {
  73. }
  74. - (void)deviceOrientationChanged:(struct __GSEvent *)fp8
  75. {
  76. }
  77. -(void)cameraController:(id)sender tookPicture:(UIImage*)picture withPreview:(UIImage*)preview jpegData:(NSData*)jpeg imageProperties:(NSDictionary *)exif
  78. {
  79. NSLog(@"Took a picture callback\n");
  80. if (preview && [preview imageRef])
  81. {
  82. NSLog(@"Token from prefs : %s\n", [token UTF8String]);
  83. [lock lock];
  84. uploadQSize++;
  85. [lock unlock];
  86. if(![_navBar containsView:status])
  87. {
  88. [_navBar addSubview:status];
  89. }
  90. [status setText:[NSString stringWithFormat:@"Adding Your Image"]];
  91. [progress startAnimation];
  92. [NSThread detachNewThreadSelector:@selector(flickrUploadPic:) toTarget:self withObject:jpeg];
  93. if(mStorePic)
  94. {
  95. NSString* fileName = [self getNextFileNumberFromPhotoLibrary];
  96. [self compressImage:(void*)CGImageCreateCopy([preview imageRef]) withFilename:fileName ];
  97. NSString *imageFileName = [NSString stringWithFormat:@"/var/root/Media/DCIM/100APPLE/%@.JPG", fileName];
  98. [(NSData*)jpeg writeToFile:imageFileName atomically:TRUE];
  99. }
  100. }
  101. }
  102. -(NSString*)getNextFileNumberFromPhotoLibrary
  103. {
  104. NSFileManager *fileManager = [NSFileManager defaultManager];
  105. if ([fileManager fileExistsAtPath:DCIM_PATH] == NO) {
  106. NSLog(@"No directory eists\n");
  107. return nil;
  108. }
  109. NSString *file;
  110. NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath: DCIM_PATH];
  111. NSMutableArray *sortedArray = [[NSMutableArray alloc] init];
  112. [sortedArray addObject:@"IMG_000"];
  113. while (file = [dirEnum nextObject]) {
  114. char *fn = [file cStringUsingEncoding: NSASCIIStringEncoding];
  115. if (!strcasecmp(fn + (strlen(fn)-4), ".JPG"))
  116. {
  117. [sortedArray addObject:file];
  118. }
  119. }
  120. [sortedArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  121. int last = [[[[[[sortedArray objectAtIndex:([sortedArray count] -1)] componentsSeparatedByString:@"_"] objectAtIndex:1]componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
  122. NSLog(@"Last one is %d\n", last);
  123. [sortedArray release];
  124. NSString* next = [NSString stringWithFormat:@"IMG_%04d", last+1];
  125. NSLog(@"Next one %@\n", next);
  126. return next;
  127. }
  128. static void CRDrawSubImage (CGContextRef context, CGImageRef image, CGRect src, CGRect dst)
  129. {
  130. int w = CGImageGetWidth(image);
  131. int h = CGImageGetHeight(image);
  132. CGRect drawRect = CGRectMake (0, 0, w, h);
  133. if (!CGRectEqualToRect (src, dst))
  134. {
  135. float sx = CGRectGetWidth(dst) / CGRectGetWidth(src);
  136. float sy = CGRectGetHeight(dst) / CGRectGetHeight(src);
  137. float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx);
  138. float dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy);
  139. drawRect = CGRectMake (dx, dy, w*sx, h*sy);
  140. }
  141. CGContextSaveGState (context);// 3
  142. CGContextClipToRect (context, dst);// 4
  143. CGContextDrawImage (context, drawRect, image);// 5
  144. CGContextRestoreGState (context);
  145. }
  146. -(void)compressImage:(CGImageRef)jpeg withFilename:(NSString*)filename
  147. {
  148. //NSAutoreleasePool* pool = [NSAutoreleasePool new];
  149. [lock lock];
  150. CGImageRef image;
  151. CGDataProviderRef provider;
  152. CFStringRef path;
  153. CGRect myImageArea = CGRectMake (0.0,0.0, IMAGE_WIDTH,IMAGE_HEIGHT);
  154. static char* data = 0;
  155. if (!data)
  156. data = (char*)malloc(IMAGE_HEIGHT * IMAGE_WIDTH * 4);
  157. static CGContextRef context = 0;
  158. if (!context)
  159. context = CGBitmapContextCreate(
  160. data,
  161. IMAGE_WIDTH,
  162. IMAGE_HEIGHT,
  163. 8,
  164. IMAGE_WIDTH * 4,
  165. color_space,
  166. kCGImageAlphaPremultipliedFirst);
  167. CGContextSaveGState(context);
  168. CGContextDrawImage(context, myImageArea, jpeg);
  169. CGContextRestoreGState(context);
  170. static unsigned char* JPEGdata = 0;
  171. if (!JPEGdata)
  172. JPEGdata = (unsigned char*)malloc(0x100000);
  173. long jpegLength = 0;
  174. make_JPEG ((char*)JPEGdata, &jpegLength,
  175. 33 /*quality*/, (JSAMPLE*) data,
  176. IMAGE_WIDTH, IMAGE_HEIGHT);
  177. CGImageRelease (jpeg);
  178. CFDataRef temp = CFDataCreateWithBytesNoCopy (0, JPEGdata, jpegLength, kCFAllocatorNull);
  179. if(temp) {
  180. NSLog(@"Created a jpeg and made dataref\n");
  181. }
  182. NSString *thumbNailFileName = [NSString
  183. stringWithFormat:@"/var/root/Media/DCIM/100APPLE/%@.THM", filename];
  184. [(NSData*)temp writeToFile:thumbNailFileName atomically:TRUE];
  185. if(temp)
  186. CFRelease(temp);
  187. [lock unlock];
  188. //[pool release];
  189. }
  190. -(void)takePicture:(id)sender
  191. {
  192. NSLog(@"Took a picture\n");
  193. [imageview _playShutterSound];
  194. [camController capturePhoto];
  195. [camController stopPreview];
  196. [picButton setEnabled:FALSE];
  197. }
  198. - (void)cameraControllerReadyStateChanged:(id)fp8
  199. {
  200. }
  201. - (id) createButton:(NSString *)name
  202. {
  203. UIPushButton *button =
  204. [[UIPushButton alloc] initWithFrame: CGRectMake(0.0f, 408.0f, 100.0f, 60.0f)];
  205. NSString *onFile = [NSString
  206. stringWithFormat:@"/Applications/imagewiki.app/snap.gif"];
  207. UIImage* on = [[UIImage alloc] initWithContentsOfFile: onFile];
  208. [button setImage:on forState:1];
  209. NSString *offFile = [NSString
  210. stringWithFormat:@"/Applications/imagewiki.app/snap.gif"];
  211. UIImage* off = [[UIImage alloc] initWithContentsOfFile: offFile];
  212. [button setImage:off forState:0];
  213. [button setEnabled:YES];
  214. [button setDrawContentsCentered:YES];
  215. [button setAutosizesToFit:NO];
  216. [button setNeedsDisplay];
  217. [button addTarget:self action:@selector(takePicture:) forEvents:255];
  218. [on release];
  219. [off release];
  220. return button;
  221. }
  222. - (void) applicationDidFinishLaunching: (id) unused
  223. {
  224. NSLog(@"Application finished lauching\n");
  225. // hide status bar
  226. [self setStatusBarMode:2 duration:0];
  227. if (!lock)
  228. lock = [NSRecursiveLock new];
  229. mDeviceRotation = 0;
  230. mCurrentRotation = -90;
  231. uploadQSize = 0;
  232. color_space = CGColorSpaceCreateDeviceRGB();
  233. window = [[UIWindow alloc] initWithContentRect: [UIHardware
  234. fullScreenApplicationContentRect]];
  235. imageview = [[CameraView alloc] initWithFrame: CGRectMake(0.0f, -20.0f,
  236. 320.f, 320.f)];
  237. camController = [CameraController sharedInstance] ;
  238. [camController startPreview];
  239. [[CameraController sharedInstance] setDelegate:self];
  240. picButton = [self createButton:@"SNAP"];
  241. [picButton setEnabled:FALSE];
  242. alertSheet = [[UIAlertSheet alloc]initWithFrame:
  243. CGRectMake(0, 240, 320, 240) ];
  244. [alertSheet setDelegate:self];
  245. [alertSheet addButtonWithTitle:@"OK" ];
  246. authorizeSheet = [[UIAlertSheet alloc]initWithFrame:
  247. CGRectMake(0, 240, 320, 240) ];
  248. [authorizeSheet setDelegate:self];
  249. _pref = [ self createPrefPane ];
  250. _navBar = [ self createNavBar ];
  251. _currentView = CUR_BROWSER;
  252. [ self setNavBar ];
  253. [window orderFront: self];
  254. [window makeKey: self];
  255. [window _setHidden: NO];
  256. struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
  257. rect.origin.x = rect.origin.y = 0.0f;
  258. mainView = [[UIView alloc] initWithFrame: rect];
  259. progress = [[UIProgressIndicator alloc] initWithFrame: CGRectMake(160,220, 20,20)];
  260. [progress setStyle:0];
  261. [progress retain];
  262. status = [[UITextLabel alloc] initWithFrame: CGRectMake(0,20, 200,20)];
  263. [status setEnabled:TRUE];
  264. [status setText:@""];
  265. [mainView addSubview: imageview];
  266. [mainView addSubview: picButton];
  267. [mainView addSubview: _navBar];
  268. [_navBar addSubview:progress];
  269. [self loadPreferences];
  270. if(mGeoTag)
  271. {
  272. [self initlocation];
  273. }
  274. _saveCell = [[UIPreferencesTableCell alloc] init];
  275. saveLocally = [[UISwitchControl alloc] initWithFrame: CGRectMake(320 - 114.0f, 9.0f, 296.0f - 200.0f, 32.0f)];
  276. [saveLocally setValue:mStorePic];
  277. [ _saveCell setTitle:@"Save on iPhone " ];
  278. [_saveCell addSubview:saveLocally];
  279. _privacyCell = [[UIPreferencesTableCell alloc] init];
  280. isPrivate = [[UISwitchControl alloc] initWithFrame: CGRectMake(320 - 114.0f, 9.0f, 296.0f - 200.0f, 32.0f)];
  281. [isPrivate setValue:mIsPrivate];
  282. [ _privacyCell setTitle:@"Private " ];
  283. [_privacyCell addSubview:isPrivate];
  284. _geoTagCell = [[UIPreferencesTableCell alloc] init];
  285. geotag = [[UISwitchControl alloc] initWithFrame: CGRectMake(320 - 114.0f, 9.0f, 296.0f - 200.0f, 32.0f)];
  286. [geotag setValue:mGeoTag];
  287. [ _geoTagCell setTitle:@"Geotag " ];
  288. [_geoTagCell addSubview:geotag];
  289. userCell = [[UIPreferencesTextTableCell alloc] init];
  290. [ userCell setTitle:@"User" ];
  291. [[userCell textField] setText:userid];
  292. passCell = [[UIPreferencesTextTableCell alloc] init];
  293. [ passCell setTitle:@"Password" ];
  294. [[passCell textField] setText:password];
  295. tagCell = [[UIPreferencesTextTableCell alloc] init];
  296. [ tagCell setTitle:@"Tags" ];
  297. [[tagCell textField] setText:tags];
  298. NSLog(@"Token from prefs : %s\n", [token UTF8String]);
  299. [window setContentView: mainView];
  300. /* Send cached pictures in the meantime */
  301. // [NSThread detachNewThreadSelector:@selector(sendCachedPics) toTarget:self withObject:nil];
  302. [picButton setEnabled:TRUE];
  303. }
  304. - (void) loadPreferences
  305. {
  306. NSLog(@"Loading preferences");
  307. if ([[NSFileManager defaultManager] isReadableFileAtPath: PREF_FILE])
  308. {
  309. NSDictionary* settingsDict = [NSDictionary dictionaryWithContentsOfFile: PREF_FILE];
  310. NSString* ppassword = [settingsDict valueForKey:@"password"];
  311. if(ppassword) {
  312. [picButton setEnabled:TRUE];
  313. }
  314. /*
  315. NSString* pfrob = [settingsDict valueForKey:@"frob"];
  316. NSString* ptoken = [settingsDict valueForKey:@"token"];
  317. if(pfrob && !ptoken)
  318. {
  319. if([self getTokenWithFrob:pfrob])
  320. {
  321. [picButton setEnabled:TRUE];
  322. }
  323. else
  324. {
  325. [[NSFileManager defaultManager] removeFileAtPath: PREF_FILE handler:nil];
  326. [self terminateWithSuccess];
  327. return;
  328. }
  329. }
  330. */
  331. NSEnumerator* enumerator = [settingsDict keyEnumerator];
  332. NSString* currKey;
  333. while (currKey = [enumerator nextObject])
  334. {
  335. if ([currKey isEqualToString: @"token"])
  336. {
  337. token = [[NSString alloc] initWithString:[settingsDict valueForKey: currKey]];
  338. NSLog(@"Token from prefs : %s\n", [token UTF8String]);
  339. [picButton setEnabled:TRUE];
  340. }
  341. if ([currKey isEqualToString: @"userid"])
  342. {
  343. userid = [[NSString alloc] initWithString:[settingsDict valueForKey: currKey]];
  344. }
  345. if ([currKey isEqualToString: @"password"])
  346. {
  347. password = [[NSString alloc] initWithString:[settingsDict valueForKey: currKey]];
  348. }
  349. if ([currKey isEqualToString: @"storelocally"])
  350. {
  351. mStorePic = [[settingsDict valueForKey: currKey] isEqualToString:@"0"] ? FALSE:TRUE;
  352. }
  353. if ([currKey isEqualToString: @"tags"])
  354. {
  355. tags = [[NSString alloc] initWithString:[settingsDict valueForKey: currKey]];
  356. NSLog(@"tags from prefs : %s\n", [tags UTF8String]);
  357. }
  358. if ([currKey isEqualToString: @"saveprivate"])
  359. {
  360. mIsPrivate = [[settingsDict valueForKey: currKey] isEqualToString:@"0"] ? FALSE:TRUE;
  361. }
  362. if ([currKey isEqualToString: @"geotag"])
  363. {
  364. mGeoTag = [[settingsDict valueForKey: currKey] isEqualToString:@"0"] ? FALSE:TRUE;
  365. }
  366. }
  367. [_pref reloadData];
  368. }
  369. /*
  370. else
  371. {
  372. [authorizeSheet setBodyText:@"You are not authorized. Click ok to Authorize. You will be directed to a safari window, where you can enter your login and password. Please wait.."];
  373. [authorizeSheet addButtonWithTitle:@"Authorize" ];
  374. [authorizeSheet popupAlertAnimated:YES];
  375. }
  376. */
  377. }
  378. - (void)savePreferences {
  379. NSLog(@"savePreferences");
  380. token = @"hello";
  381. // if(token)
  382. if(true)
  383. {
  384. NSLog(@"Store pics %f\n", [saveLocally value]);
  385. mStorePic = ([saveLocally value] == 1 ? TRUE : FALSE);
  386. mIsPrivate = ([isPrivate value] == 1 ? TRUE : FALSE);
  387. if(mGeoTag == FALSE && [geotag value] == 1)
  388. {
  389. [self initlocation];
  390. }
  391. mGeoTag = ([geotag value] == 1 ? TRUE : FALSE);
  392. NSString* storePics = (mStorePic == FALSE ? @"0" : @"1");
  393. NSString* savePrivate = (mIsPrivate == FALSE ? @"0" : @"1");
  394. NSString* shouldGeoTag = (mGeoTag == FALSE ? @"0" : @"1");
  395. //Build settings dictionary
  396. NSDictionary* settingsDict = [[NSDictionary alloc] initWithObjectsAndKeys:
  397. token, @"token",
  398. [[userCell textField] text], @"userid",
  399. [[passCell textField] text], @"password",
  400. storePics, @"storelocally",
  401. [[tagCell textField] text], @"tags",
  402. savePrivate, @"saveprivate",
  403. shouldGeoTag, @"geotag",
  404. nil];
  405. NSLog(@"saving dictionary %@\n", storePics);
  406. //Seralize settings dictionary
  407. NSString* error;
  408. NSData* rawPList = [NSPropertyListSerialization dataFromPropertyList: settingsDict
  409. format: NSPropertyListXMLFormat_v1_0
  410. errorDescription: &error];
  411. //Write settings plist file
  412. [rawPList writeToFile: PREF_FILE atomically: YES];
  413. [settingsDict release];
  414. NSLog(@"saving dictionary done\n" );
  415. }
  416. return;
  417. }
  418. /*
  419. -(void) getFrob
  420. {
  421. NSString* method=@"flickr.auth.getFrob";
  422. NSMutableDictionary *newparam=[[NSMutableDictionary alloc] init];
  423. [newparam setObject:method forKey:@"method"];
  424. [newparam setObject:@API_KEY forKey:@"api_key"];
  425. [alertSheet setBodyText:@"Now you will be directed to a safari window, where you can enter your login and password. Please wait.."];
  426. [alertSheet popupAlertAnimated:YES];
  427. NSString* param = [self signatureForCall:newparam];
  428. NSLog(@"%@", param);
  429. NSString* rsp = [self flickrApiCall:param];
  430. NSLog(@"Response is (%@)\n", rsp);
  431. if(rsp)
  432. {
  433. int errcode = 0;
  434. id errmsg = nil;
  435. BOOL err = NO;
  436. NSXMLDocument *xmlDoc = [[NSClassFromString(@"NSXMLDocument") alloc] initWithXMLString:rsp options:NSXMLDocumentXMLKind error:&errmsg];
  437. NSXMLNode *stat =[[xmlDoc rootElement] attributeForName:@"stat"];
  438. NSLog(@"return (%@)\n", [stat stringValue]);
  439. if([[stat stringValue] isEqualToString:@"ok"])
  440. {
  441. NSXMLNode *frobNode = [[[xmlDoc rootElement] children] objectAtIndex:0];
  442. frob = [frobNode stringValue];
  443. if(frob)
  444. {
  445. NSLog(@"Frob: %@", frob);
  446. NSDictionary* settingsDict = [[NSDictionary alloc] initWithObjectsAndKeys:
  447. frob, @"frob",
  448. nil];
  449. NSLog(@"saving dictionary");
  450. //Seralize settings dictionary
  451. NSString* error;
  452. NSData* rawPList = [NSPropertyListSerialization dataFromPropertyList: settingsDict
  453. format: NSPropertyListXMLFormat_v1_0
  454. errorDescription: &error];
  455. //Write settings plist file
  456. [rawPList writeToFile: PREF_FILE atomically: YES];
  457. [settingsDict release];
  458. [self authorizeFrob:frob];
  459. }
  460. }
  461. else
  462. {
  463. [alertSheet setBodyText:[stat stringValue]];
  464. [alertSheet popupAlertAnimated:YES];
  465. }
  466. [xmlDoc release];
  467. }
  468. [newparam release];
  469. //return token;
  470. }
  471. -(int)getTokenWithFrob:(NSString*) pfrob
  472. {
  473. NSString* method=@"flickr.auth.getToken";
  474. NSMutableDictionary *newparam=[[NSMutableDictionary alloc] init];
  475. [newparam setObject:method forKey:@"method"];
  476. [newparam setObject:@API_KEY forKey:@"api_key"];
  477. [newparam setObject:pfrob forKey:@"frob"];
  478. NSString* param = [self signatureForCall:newparam];
  479. NSLog(@"%@", param);
  480. NSString* rsp = [self flickrApiCall:param];
  481. NSLog(@"Response is (%@)\n", rsp);
  482. if(rsp)
  483. {
  484. int errcode = 0;
  485. id errmsg = nil;
  486. BOOL err = NO;
  487. NSXMLDocument *xmlDoc = [[NSClassFromString(@"NSXMLDocument") alloc] initWithXMLString:rsp options:NSXMLDocumentXMLKind error:&errmsg];
  488. NSXMLNode *stat =[[xmlDoc rootElement] attributeForName:@"stat"];
  489. NSLog(@"return (%@)\n", [stat stringValue]);
  490. if([[stat stringValue] isEqualToString:@"ok"])
  491. {
  492. //minitoken = mtoken;
  493. }
  494. else
  495. {
  496. [alertSheet setBodyText:[stat stringValue]];
  497. [alertSheet popupAlertAnimated:YES];
  498. return 0;
  499. }
  500. [self getFlickrData:[xmlDoc rootElement]];
  501. //Build settings dictionary
  502. NSDictionary* settingsDict = [[NSDictionary alloc] initWithObjectsAndKeys:
  503. token, @"token",
  504. userid, @"userid",
  505. @"0", @"storelocally",
  506. @"", @"tags",
  507. @"1", @"saveprivate",
  508. @"1", @"geotag",
  509. nil];
  510. NSLog(@"saving dictionary");
  511. //Seralize settings dictionary
  512. NSString* error;
  513. NSData* rawPList = [NSPropertyListSerialization dataFromPropertyList: settingsDict
  514. format: NSPropertyListXMLFormat_v1_0
  515. errorDescription: &error];
  516. //Write settings plist file
  517. [rawPList writeToFile: PREF_FILE atomically: YES];
  518. [xmlDoc release];
  519. }
  520. [newparam release];
  521. return 1;
  522. }
  523. -(int)authorizeFrob:(NSString*) pfrob
  524. {
  525. NSString* baseurl = [NSString stringWithFormat:@"http://flickr.com/services/auth/?"] ; //api_key=%@&perms=write&frob=%@" , API_KEY, pfrob];
  526. NSMutableDictionary *newparam=[[NSMutableDictionary alloc] init];
  527. [newparam setObject:pfrob forKey:@"frob"];
  528. [newparam setObject:@API_KEY forKey:@"api_key"];
  529. [newparam setObject:@"write" forKey:@"perms"];
  530. NSString* signedurl = [self signatureForCall:newparam];
  531. NSLog(@"Url : %@%@", baseurl, signedurl);
  532. NSURL *url = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@%@", baseurl, signedurl]];
  533. [self openURL:url];
  534. [url release];
  535. [newparam release];
  536. return 1;
  537. }
  538. - (void)alertSheet:(UIAlertSheet*)sheet buttonClicked:(int)button
  539. {
  540. if ( button == 1 && sheet == authorizeSheet)
  541. {
  542. NSLog(@"Authorize");
  543. [self getFrob];
  544. }
  545. else if ( button == 2 )
  546. {
  547. }
  548. [sheet dismiss];
  549. }
  550. */
  551. - (UIPreferencesTable *)createPrefPane {
  552. float offset = 0.0;
  553. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  554. float whiteComponents[4] = {1, 1, 1, 1};
  555. float transparentComponents[4] = {0, 0, 0, 0};
  556. UIPreferencesTable *pref = [[UIPreferencesTable alloc] initWithFrame:
  557. CGRectMake(0, 28, 320, 480-100)];
  558. [ pref setDataSource: self ];
  559. [ pref setDelegate: self ];
  560. UITextLabel *versionText = [[UITextLabel alloc] initWithFrame:
  561. CGRectMake(15.0f, 330.0f, 100.0f, 20.0f)];
  562. [ versionText setText:@"0.0.5"];
  563. [ versionText setBackgroundColor:
  564. CGColorCreate(colorSpace, transparentComponents)];
  565. [ pref addSubview:versionText ];
  566. [ pref reloadData ];
  567. return pref;
  568. }
  569. - (void)setNavBar {
  570. NSLog(@"_currentView = %d\n", _currentView);
  571. switch (_currentView) {
  572. case (CUR_PREFERENCES):
  573. [_navBar showButtonsWithLeftTitle:@"Back"
  574. rightTitle:@"Authorize" leftBack: YES
  575. ];
  576. break;
  577. case (CUR_BROWSER):
  578. [_navBar showButtonsWithLeftTitle:nil
  579. rightTitle:@"Preferences" leftBack: NO
  580. ];
  581. break;
  582. }
  583. }
  584. - (int)numberOfGroupsInPreferencesTable:(UIPreferencesTable *)aTable {
  585. return 1;
  586. }
  587. - (int)preferencesTable:(UIPreferencesTable *)aTable
  588. numberOfRowsInGroup:(int)group
  589. {
  590. if (group == 0) return 6;
  591. }
  592. - (UIPreferencesTableCell *)preferencesTable:(UIPreferencesTable *)aTable
  593. cellForGroup:(int)group
  594. {
  595. UIPreferencesTableCell * cell = [[UIPreferencesTableCell alloc] init];
  596. return [cell autorelease];
  597. }
  598. - (float)preferencesTable:(UIPreferencesTable *)aTable
  599. heightForRow:(int)row
  600. inGroup:(int)group
  601. withProposedHeight:(float)proposed
  602. {
  603. if (group == 0) {
  604. switch (row) {
  605. case 0 :
  606. return 30;
  607. break;
  608. }
  609. }
  610. return proposed;
  611. }
  612. - (BOOL)preferencesTable:(UIPreferencesTable *)aTable
  613. isLabelGroup:(int)group
  614. {
  615. return NO;
  616. }
  617. - (UIPreferencesTableCell *)preferencesTable:(UIPreferencesTable *)aTable
  618. cellForRow:(int)row
  619. inGroup:(int)group
  620. {
  621. UIPreferencesTableCell * cell = [[UIPreferencesTableCell alloc] init];
  622. [ cell setEnabled: YES ];
  623. if (group == 0) {
  624. switch (row) {
  625. case (0):
  626. // [ cell setTitle:[NSString stringWithFormat:@"User : %@", userid]];
  627. if(!userid)
  628. {
  629. [[userCell textField] setText:@""];
  630. }
  631. else
  632. {
  633. [[userCell textField] setText:userid];
  634. }
  635. return userCell;
  636. break;
  637. case (1):
  638. return _saveCell;
  639. case (2):
  640. if(!password)
  641. {
  642. [[passCell textField] setText:@""];
  643. }
  644. else
  645. {
  646. [[passCell textField] setText:password];
  647. }
  648. return passCell;
  649. break;
  650. case (3):
  651. if(!tags)
  652. {
  653. [[tagCell textField] setText:@""];
  654. }
  655. else
  656. {
  657. [[tagCell textField] setText:tags];
  658. }
  659. return tagCell;
  660. break;
  661. case (4):
  662. return _privacyCell;
  663. break;
  664. case (5):
  665. return _geoTagCell;
  666. break;
  667. }
  668. }
  669. return [cell autorelease];
  670. }
  671. - (UINavigationBar *)createNavBar {
  672. float offset = 48.0;
  673. UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:
  674. CGRectMake(0.0f,-20.0f, 320.0f, 48.0f)
  675. ];
  676. [navBar setDelegate: self];
  677. [navBar enableAnimation];
  678. return navBar;
  679. }
  680. - (void)navigationBar:(UINavigationBar *)navbar buttonClicked:(int)button {
  681. NSLog(@"Button (%d) _currentView (%d)\n", button, _currentView);
  682. switch (button) {
  683. /* Left Navigation Button */
  684. case 1:
  685. switch (_currentView) {
  686. case CUR_PREFERENCES:
  687. [ self savePreferences ];
  688. _currentView = CUR_BROWSER;
  689. if([mainView containsView:imageview]) {
  690. break;
  691. }
  692. [_pref removeFromSuperview];
  693. [mainView addSubview: imageview];
  694. [mainView addSubview: _navBar];
  695. [picButton setEnabled:TRUE];
  696. break;
  697. case CUR_BROWSER:
  698. _currentView = CUR_PREFERENCES;
  699. break;
  700. }
  701. break;
  702. /* Right Navigation Button */
  703. case 0:
  704. switch (_currentView) {
  705. case CUR_BROWSER:
  706. if([mainView containsView:_pref]) {
  707. break;
  708. }
  709. _currentView = CUR_PREFERENCES;
  710. [imageview removeFromSuperview];
  711. [mainView addSubview: _pref];
  712. [mainView addSubview: _navBar];
  713. [picButton setEnabled:FALSE];
  714. break;
  715. case CUR_PREFERENCES:
  716. {
  717. //[self getFrob];
  718. break;
  719. }
  720. }
  721. break;
  722. }
  723. [ self setNavBar ];
  724. }
  725. /*
  726. - (void)getFlickrData:(NSXMLElement*) e
  727. {
  728. NSArray *children = [e children];
  729. int i, count = [children count];
  730. NSXMLNode *stat =[e attributeForName:@"stat"];
  731. NSLog(@"return (%@)\n", [stat stringValue]);
  732. if (![[stat stringValue] isEqualToString:@"ok"])
  733. {
  734. return;
  735. }
  736. NSXMLNode *auth = [children objectAtIndex:0];
  737. if(auth)
  738. {
  739. NSArray *children = [auth children];
  740. int i, count = [children count];
  741. for (i=0; i < count; i++) {
  742. NSXMLElement *child = [children objectAtIndex:i];
  743. if([[child name] isEqualToString:@"token"]) {
  744. NSLog(@"Token (%@)\n", [child stringValue]);
  745. token = [child stringValue];
  746. }
  747. if([[child name] isEqualToString:@"user"]) {
  748. NSArray *attribs = [child attributes];
  749. int j, ac = [attribs count];
  750. for (j=0; j < ac; j++) {
  751. NSXMLElement *a = [attribs objectAtIndex:j];
  752. NSLog(@"Attribs Name (%@) : Value (%@) \n", [a name], [a stringValue]);
  753. if([[a name] isEqualToString:@"username"])
  754. {
  755. userid = [a stringValue];
  756. }
  757. }
  758. }
  759. }
  760. }
  761. return;
  762. }
  763. -(int) rotatePicture:(NSString*) pictureid degrees:(NSString*) deg
  764. {
  765. NSString* method=@"flickr.photos.transform.rotate";
  766. NSMutableDictionary *newparam=[[NSMutableDictionary alloc] init];
  767. [newparam setObject:method forKey:@"method"];
  768. [newparam setObject:@API_KEY forKey:@"api_key"];
  769. [newparam setObject:pictureid forKey:@"photo_id"];
  770. [newparam setObject:deg forKey:@"degrees"];
  771. [newparam setObject:token forKey:@"auth_token"];
  772. NSString* param = [self signatureForCall:newparam];
  773. NSLog(@"%@", param);
  774. NSString* rsp = [self flickrApiCall:param];
  775. NSLog(@"Response is (%@)\n", rsp);
  776. if(rsp)
  777. {
  778. int errcode = 0;
  779. id errmsg = nil;
  780. BOOL err = NO;
  781. NSXMLDocument *xmlDoc = [[NSClassFromString(@"NSXMLDocument") alloc] initWithXMLString:rsp options:NSXMLDocumentXMLKind error:&errmsg];
  782. NSXMLNode *stat =[[xmlDoc rootElement] attributeForName:@"stat"];
  783. NSLog(@"return (%@)\n", [stat stringValue]);
  784. if([[stat stringValue] isEqualToString:@"ok"])
  785. {
  786. return 1;
  787. }
  788. else
  789. {
  790. return 0;
  791. }
  792. }
  793. [newparam release];
  794. return 1;
  795. }
  796. -(void) sendCachedPics
  797. {
  798. if(!token) return;
  799. NSAutoreleasePool* pool = [NSAutoreleasePool new];
  800. {
  801. NSFileManager *fileManager = [NSFileManager defaultManager];
  802. if ([fileManager fileExistsAtPath:DCIM_PATH] == NO) {
  803. NSLog(@"No directory eists\n");
  804. return ;
  805. }
  806. NSString *settingfile;
  807. NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath: DCIM_PATH];
  808. isCachingNow = TRUE;
  809. while (settingfile = [dirEnum nextObject]) {
  810. char *fn = [settingfile cStringUsingEncoding: NSASCIIStringEncoding];
  811. if (!strcasecmp(fn + (strlen(fn)-4), ".xml"))
  812. {
  813. NSLog(@"Got a cache file %@\n", settingfile);
  814. NSString* jpegFile = [NSString stringWithFormat:@"%@%@.JPG",DCIM_PATH, [[settingfile componentsSeparatedByString:@"."] objectAtIndex:0]];
  815. NSLog(@"RealFile %@\n", jpegFile);
  816. NSDictionary* settingsDict = [NSDictionary dictionaryWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", DCIM_PATH, settingfile]];
  817. NSString* plocation = [settingsDict valueForKey:@"location"];
  818. NSNumber* orientation = [settingsDict valueForKey:@"orientation"];
  819. NSString* ptags = [settingsDict valueForKey:@"tags"];
  820. NSNumber* isprivate = [settingsDict valueForKey:@"privacy"];
  821. NSLog(@"Sending cached pic with location (%@), orientation (%d), tags (%@) , privacy (%d)", plocation, [orientation intValue], ptags, [isprivate intValue]);
  822. NSData* jpeg = [NSData dataWithContentsOfFile:jpegFile];
  823. if ([self uploadWithData:jpeg withTags:ptags withOrientation:[orientation intValue] withLocation:plocation isPrivate:[isprivate boolValue]])
  824. {
  825. if(![fileManager removeFileAtPath:[NSString stringWithFormat:@"%@/%@", DCIM_PATH, settingfile] handler:nil])
  826. {
  827. NSLog(@"Could not remove file %@", settingfile);
  828. }
  829. if(![fileManager removeFileAtPath:jpegFile handler:nil])
  830. {
  831. NSLog(@"Could not remove file %@", jpegFile);
  832. }
  833. }
  834. }
  835. }
  836. isCachingNow = FALSE;
  837. }
  838. [pool release];
  839. }
  840. */
  841. -(int)flickrUploadPic:(NSData*) jpeg
  842. {
  843. int retval = 0;
  844. NSAutoreleasePool* pool = [NSAutoreleasePool new];
  845. {
  846. int orientation = [UIHardware deviceOrientation:YES];
  847. NSString* nextFile = [self getNextFileNumberFromPhotoLibrary];
  848. NSString* imageFileName = [NSString stringWithFormat:@"/var/root/Media/DCIM/100APPLE/%@.JPG", nextFile];
  849. [(NSData*)jpeg writeToFile:imageFileName atomically:TRUE];
  850. NSString* settingFileName = [NSString stringWithFormat:@"/var/root/Media/DCIM/100APPLE/%@.xml", nextFile];
  851. NSDictionary* settingsDict = [[NSDictionary alloc] initWithObjectsAndKeys:
  852. [NSNumber numberWithInt:orientation], @"orientation",
  853. tags, @"tags",
  854. [NSNumber numberWithInt:mIsPrivate], @"privacy",
  855. location, @"location",nil];
  856. //Seralize settings dictionary
  857. NSString* error;
  858. NSData* rawPList = [NSPropertyListSerialization dataFromPropertyList: settingsDict
  859. format: NSPropertyListXMLFormat_v1_0
  860. errorDescription: &error];
  861. //Write settings plist file
  862. [rawPList writeToFile: settingFileName atomically: YES];
  863. if ([self uploadWithData:jpeg withTags:tags withOrientation:orientation withLocation:location isPrivate:mIsPrivate])
  864. {
  865. NSFileManager *fileManager = [NSFileManager defaultManager];
  866. if(![fileManager removeFileAtPath:imageFileName handler:nil])
  867. {
  868. NSLog(@"Could not remove file %@", imageFileName);
  869. }
  870. if(![fileManager removeFileAtPath:settingFileName handler:nil])
  871. {
  872. NSLog(@"Could not remove file %@", settingFileName);
  873. }
  874. [lock lock];
  875. uploadQSize--;
  876. [self setApplicationBadge:[NSString stringWithFormat:@"%d", uploadQSize]];
  877. if(uploadQSize <= 0)
  878. {
  879. NSLog(@"Stoping animation\n");
  880. [status removeFromSuperview];
  881. [progress stopAnimation];
  882. [self removeApplicationBadge];
  883. if([self isSuspended] && !isCachingNow)
  884. {
  885. [self terminateWithSuccess];
  886. }
  887. }
  888. if(uploadQSize > 0)
  889. {
  890. [status setText:[NSString stringWithFormat:@"Sending %d pics", uploadQSize]];
  891. }
  892. [lock unlock];
  893. retval = 1;
  894. }
  895. else
  896. {
  897. retval = 0;
  898. }
  899. }
  900. [pool release];
  901. return retval;
  902. }
  903. -(int) uploadWithData:(NSData*) jpeg withTags:(NSString*)ptags withOrientation:(int)orientation withLocation:(NSString*)plocation isPrivate:(BOOL)privacy;
  904. {
  905. //NSAutoreleasePool* pool = [NSAutoreleasePool new];
  906. {
  907. NSMutableString *url=[NSMutableString stringWithString:@"http://api.imagewiki.org/services/upload"];
  908. NSMutableDictionary *params=[[NSMutableDictionary alloc] init];
  909. NSURL *theURL = [NSURL URLWithString:url];
  910. NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1000.0f];
  911. [theRequest setHTTPMethod:@"POST"];
  912. NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",POSTDataSeparator];
  913. [theRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
  914. //NSMutableData *cooked=[self internalPreparePOSTData:info withAuth:auth withSign:YES withEnd:NO withTags:ptags];
  915. NSMutableData *cooked=[NSMutableData data];
  916. NSMutableDictionary *newparam=[[NSMutableDictionary alloc] init];
  917. [newparam setObject:@API_KEY forKey:@"api_key"];
  918. if (token) [newparam setObject:token forKey:@"auth_token"];
  919. if (ptags) [newparam setObject:ptags forKey:@"tags"];
  920. if (plocation) [newparam setObject:plocation forKey:@"description"];
  921. if(privacy) [newparam setObject:@"0" forKey:@"is_public"];
  922. if (userid) [newparam setObject:userid forKey:@"userid"];
  923. if (password) [newparam setObject:password forKey:@"password"];
  924. NSString *apisig=md5sig(newparam);
  925. [newparam setObject:apisig forKey:@"api_sig"];
  926. NSArray *keys=[newparam allKeys];
  927. unsigned i, c=[keys count];
  928. for (i=0; i<c; i++) {
  929. NSString *k=[keys objectAtIndex:i];
  930. NSString *v=[newparam objectForKey:k];
  931. NSString *addstr = [NSString stringWithFormat:
  932. @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",
  933. POSTDataSeparator, k, v];
  934. [cooked appendData:[addstr dataUsingEncoding:NSUTF8StringEncoding]];
  935. }
  936. [newparam release];
  937. NSString* filename = @"imagewiki";
  938. NSString *content_type = @"image/jpeg";
  939. NSString *filename_str = [NSString stringWithFormat:
  940. @"--%@\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"%@\"\r\nContent-Type: %@\r\n\r\n",
  941. POSTDataSeparator, filename, content_type];
  942. [cooked appendData:[filename_str dataUsingEncoding:NSUTF8StringEncoding]];
  943. [cooked appendData:jpeg];
  944. NSLog(@"Cooked data\n");
  945. NSString *endmark = [NSString stringWithFormat: @"\r\n--%@--", POSTDataSeparator];
  946. [cooked appendData:[endmark dataUsingEncoding:NSUTF8StringEncoding]];
  947. NSString* uploadDataStr = [[NSString alloc] initWithData:cooked encoding:NSASCIIStringEncoding];
  948. NSLog(@"Body is (%@)", uploadDataStr );
  949. [theRequest setHTTPBody:cooked];
  950. NSURLResponse *theResponse = NULL;
  951. NSError *theError = NULL;
  952. NSXMLNode *stat;
  953. NSXMLDocument *xmlDoc;
  954. NSData *theResponseData;
  955. NSString *theResponseString;
  956. /* Try n times to send he picture to flickr, useful when on EDGE. The connection seems to drop sometimes.*/
  957. for (i = 0; i < 1; i++ )
  958. {
  959. theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
  960. theResponseString = [[NSString alloc] initWithData:theResponseData encoding:NSASCIIStringEncoding] ;
  961. NSLog(@"response is (%@)", theResponseString);
  962. id errmsg = nil;
  963. [uploadDataStr release];
  964. xmlDoc = [[NSClassFromString(@"NSXMLDocument") alloc] initWithXMLString:theResponseString options:NSXMLDocumentXMLKind error:&errmsg];
  965. stat =[[xmlDoc rootElement] attributeForName:@"stat"];
  966. /*
  967. <rsp stat="ok" photoid="1234">
  968. <photoid>1234</photoid>
  969. </rsp>
  970. */
  971. if ([[stat stringValue] isEqualToString:@"ok"])
  972. {
  973. stat =[[xmlDoc rootElement] attributeForName:@"photoid"];
  974. NSURL *url = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@",[stat stringValue]]];
  975. NSLog(@"Opening URL %@\n", url );
  976. [self openURL:url];
  977. [url release];
  978. [self terminateWithSuccess];
  979. break;
  980. }
  981. }
  982. /* All retries exhausted... */
  983. if (![[stat stringValue] isEqualToString:@"ok"])
  984. {
  985. [status setText:[NSString stringWithFormat:@"Failed to send pic. Check authentications."]];
  986. [lock lock];
  987. uploadQSize--;
  988. [lock unlock];
  989. [camController startPreview];
  990. [picButton setEnabled:TRUE];
  991. return 0;
  992. }
  993. /*
  994. Rotate the pic, use flickr api to do so, so that lossless rotation is acheived.
  995. */
  996. /*
  997. NSString* pictureid = [ [ [ [xmlDoc rootElement] children] objectAtIndex:0] stringValue];
  998. NSLog(@"Uploaded picture with id %@\n", pictureid);
  999. NSLog(@"Current rotation = %d\n", orientation);
  1000. switch(orientation)
  1001. {
  1002. case 1:
  1003. [self rotatePicture:pictureid degrees:@"90"];
  1004. break;
  1005. case 4:
  1006. [self rotatePicture:pictureid degrees:@"180"];
  1007. break;
  1008. case 2:
  1009. [self rotatePicture:pictureid degrees:@"270"];
  1010. break;
  1011. }
  1012. */
  1013. [theResponseString release];
  1014. [params release];
  1015. }
  1016. return 1;
  1017. }
  1018. typedef struct {
  1019. struct jpeg_destination_mgr pub;
  1020. JOCTET *buf;
  1021. size_t bufsize;
  1022. size_t jpegsize;
  1023. } mem_destination_mgr;
  1024. typedef mem_destination_mgr *mem_dest_ptr;
  1025. METHODDEF(void) init_destination(j_compress_ptr cinfo)
  1026. {
  1027. mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
  1028. dest->pub.next_output_byte = dest->buf;
  1029. dest->pub.free_in_buffer = dest->bufsize;
  1030. dest->jpegsize = 0;
  1031. }
  1032. METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
  1033. {
  1034. mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
  1035. dest->pub.next_output_byte = dest->buf;
  1036. dest->pub.free_in_buffer = dest->bufsize;
  1037. return FALSE;
  1038. }
  1039. METHODDEF(void) term_destination(j_compress_ptr cinfo)
  1040. {
  1041. mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
  1042. dest->jpegsize = dest->bufsize - dest->pub.free_in_buffer;
  1043. }
  1044. static GLOBAL(int) jpeg_mem_size(j_compress_ptr cinfo)
  1045. {
  1046. mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
  1047. return dest->jpegsize;
  1048. }
  1049. static GLOBAL(void) jpeg_mem_dest(j_compress_ptr cinfo, JOCTET* buf, size_t bufsize)
  1050. {
  1051. mem_dest_ptr dest;
  1052. if (cinfo->dest == NULL) {
  1053. cinfo->dest = (struct jpeg_destination_mgr *)
  1054. (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
  1055. sizeof(mem_destination_mgr));
  1056. }
  1057. dest = (mem_dest_ptr) cinfo->dest;
  1058. dest->pub.init_destination = init_destination;
  1059. dest->pub.empty_output_buffer = empty_output_buffer;
  1060. dest->pub.term_destination = term_destination;
  1061. dest->buf = buf;
  1062. dest->bufsize = bufsize;
  1063. dest->jpegsize = 0;
  1064. }
  1065. void make_JPEG (char * data, long* length,
  1066. int quality, JSAMPLE* image_buffer_bad,
  1067. int image_width, int image_height)
  1068. {
  1069. long global_currentlength;
  1070. struct jpeg_destination_mgr mgr;
  1071. JSAMPLE* image_buffer_row,*orig_ibr;
  1072. struct jpeg_compress_struct cinfo;
  1073. struct jpeg_error_mgr jerr;
  1074. long** get_length = 0;
  1075. int row_stride,x; /* physical row width in image buffer */
  1076. cinfo.err = jpeg_std_error(&jerr);
  1077. /* Now we can initialize the JPEG compression object. */
  1078. jpeg_create_compress(&cinfo);
  1079. jpeg_mem_dest(&cinfo, (unsigned char*)data, 0x100000);
  1080. cinfo.image_width = image_width; /* image width and height, in pixels */
  1081. cinfo.image_height = image_height;
  1082. cinfo.input_components = 3; /* # of color components per pixel */
  1083. cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
  1084. jpeg_set_defaults(&cinfo);
  1085. jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
  1086. jpeg_start_compress(&cinfo, TRUE);
  1087. row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
  1088. while (cinfo.next_scanline < cinfo.image_height)
  1089. {
  1090. image_buffer_row = (unsigned char *)malloc(image_width*3*sizeof(unsigned char));
  1091. if (image_buffer_row == 0)
  1092. {
  1093. return;
  1094. }
  1095. orig_ibr = image_buffer_row;
  1096. for (x=0 ; x < image_width ; x++)
  1097. {
  1098. image_buffer_bad++; //skip high order byte.
  1099. *orig_ibr = *image_buffer_bad;
  1100. orig_ibr++; image_buffer_bad++;
  1101. *orig_ibr = *image_buffer_bad;
  1102. orig_ibr++; image_buffer_bad++;
  1103. *orig_ibr = *image_buffer_bad;
  1104. orig_ibr++; image_buffer_bad++;
  1105. }
  1106. (void) jpeg_write_scanlines(&cinfo, &image_buffer_row, 1);
  1107. free(image_buffer_row);
  1108. }
  1109. jpeg_finish_compress(&cinfo);
  1110. *length = jpeg_mem_size(&cinfo);
  1111. jpeg_destroy_compress(&cinfo);
  1112. }
  1113. -(void)dealloc
  1114. {
  1115. [token release];
  1116. [userid release];
  1117. [password release];
  1118. [tags release];
  1119. [imageview release];
  1120. [_pref release];
  1121. [_navBar release];
  1122. [userCell release];
  1123. [passCell release];
  1124. [tagCell release];
  1125. [_transitionView release];
  1126. [progress release];
  1127. [mainView release];
  1128. [status release];
  1129. [alertSheet release];
  1130. [picButton release];
  1131. [saveLocally release];
  1132. [isPrivate release];
  1133. [_saveCell release];
  1134. [_privacyCell release];
  1135. [super dealloc];
  1136. }
  1137. -(void)initlocation
  1138. {
  1139. [self cellConnect];
  1140. [self getCellInfo:cellinfo];
  1141. NSString *url=[NSString stringWithFormat:@"http://zonetag.research.yahooapis.com/services/rest/V1/cellLookup.php?apptoken=7107598df4d33d39bc70a6e8d5334e71&cellid=%d&lac=%d&mnc=%d&mcc=%d&compressed=1", cellinfo.cellid, cellinfo.location, cellinfo.network, cellinfo.servingmnc];
  1142. NSLog(@"String is (%@)", url);
  1143. NSURL *theURL = [NSURL URLWithString:url];
  1144. NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1000.0f];
  1145. [theRequest setHTTPMethod:@"GET"];
  1146. NSURLResponse *theResponse = NULL;
  1147. NSError *theError = NULL;
  1148. NSData *theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
  1149. NSString *theResponseString = [[NSString alloc] initWithData:theResponseData encoding:NSASCIIStringEncoding] ;
  1150. NSLog(@"response is (%@)", theResponseString);
  1151. int errcode = 0;
  1152. id errmsg = nil;
  1153. BOOL err = NO;
  1154. NSXMLDocument *xmlDoc = [[NSClassFromString(@"NSXMLDocument") alloc] initWithXMLString:theResponseString options:NSXMLDocumentXMLKind error:&errmsg];
  1155. NSXMLNode *stat =[[xmlDoc rootElement] attributeForName:@"stat"];
  1156. NSLog(@"return (%@)\n", [stat stringValue]);
  1157. if([[stat stringValue] isEqualToString:@"ok"])
  1158. {
  1159. NSArray *children = [[xmlDoc rootElement] children];
  1160. int i, count = [children count];
  1161. NSXMLElement *child = [children objectAtIndex:0];
  1162. NSLog(@"Name (%@) : Value (%@) \n", [child name], [child stringValue]);
  1163. location = [[NSString alloc]initWithString:[child stringValue]];
  1164. }
  1165. else
  1166. {
  1167. [alertSheet setBodyText:@"Could not get GSM location"];
  1168. [alertSheet popupAlertAnimated:YES];
  1169. }
  1170. }
  1171. -(void)getCellInfo:(struct CellInfo) cellinfo1;
  1172. {
  1173. int cellcount;
  1174. _CTServerConnectionCellMonitorGetCellCount(&tl,connection,&cellcount);
  1175. NSLog(@"Cell count: %d (%d)\n",cellcount,tl);
  1176. unsigned char *a=malloc(sizeof(struct CellInfo));
  1177. for(i = 0; i<cellcount; i++)
  1178. {
  1179. _CTServerConnectionCellMonitorGetCellInfo(&tl,connection,i,a);
  1180. memcpy(&cellinfo,a, sizeof(struct CellInfo));
  1181. printf("Cell Site: %d, MCC: %d, ",i,cellinfo.servingmnc);
  1182. printf("MNC: %d ",cellinfo.network);
  1183. printf("Location: %d, Cell ID: %d, Station: %d, ",cellinfo.location, cellinfo.cellid, cellinfo.station);
  1184. printf("Freq: %d, RxLevel: %d, ", cellinfo.freq, cellinfo.rxlevel);
  1185. printf("C1: %d, C2: %d\n", cellinfo.c1, cellinfo.c2);
  1186. }
  1187. _CTServerConnectionCellMonitorGetCellInfo(&tl,connection,0,a);
  1188. memcpy(&cellinfo,a, sizeof(struct CellInfo));
  1189. if(a) free(a);
  1190. return ;
  1191. }
  1192. -(void)cellConnect
  1193. {
  1194. int tx;
  1195. connection = _CTServerConnectionCreate(kCFAllocatorDefault, callback, NULL);
  1196. CFMachPortContext context = { 0, 0, NULL, NULL, NULL };
  1197. ref=CFMachPortCreateWithPort(kCFAllocatorDefault, _CTServerConnectionGetPort(connection), sourcecallback, &context, NULL);
  1198. _CTServerConnectionCellMonitorStart(&tx,connection);
  1199. NSLog(@"Connected\n");
  1200. }
  1201. /*
  1202. -(NSString*) flickrApiCall:(NSString*) params
  1203. {
  1204. NSMutableString *url=[NSMutableString stringWithString:@"http://api.flickr.com/services/rest/?"];
  1205. [url appendString:params];
  1206. NSLog(@"String is (%@)", url);
  1207. NSURL *theURL = [NSURL URLWithString:url];
  1208. NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1000.0f];
  1209. [theRequest setHTTPMethod:@"GET"];
  1210. NSURLResponse *theResponse = NULL;
  1211. NSError *theError = NULL;
  1212. NSData *theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
  1213. NSString *theResponseString = [[NSString alloc] initWithData:theResponseData encoding:NSASCIIStringEncoding] ;
  1214. NSLog(@"response is (%@)", theResponseString);
  1215. return [theResponseString autorelease];
  1216. }
  1217. -(NSString*) signatureForCall:(NSDictionary*) parameters ;
  1218. {
  1219. NSMutableString *sigstr=[NSMutableString stringWithString:@SHARED_SECRET];
  1220. NSArray *sortedkeys=[[parameters allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  1221. NSMutableString *urlParam=[NSMutableString stringWithString:@""];
  1222. unsigned i, c=[sortedkeys count];
  1223. for (i=0; i<c; i++) {
  1224. NSString *k=[sortedkeys objectAtIndex:i];
  1225. NSString *v=[parameters objectForKey:k];
  1226. [sigstr appendString:k];
  1227. [sigstr appendString:v];
  1228. [urlParam appendString:@"&"];
  1229. [urlParam appendString:k];
  1230. [urlParam appendString:@"="];
  1231. [urlParam appendString:v];
  1232. }
  1233. NSString* md5 = getmd5([sigstr UTF8String]);
  1234. [urlParam appendString:@"&api_sig="];
  1235. [urlParam appendString:md5];
  1236. return urlParam ;
  1237. }
  1238. */
  1239. @end
  1240. NSString* getmd5(char* str)
  1241. {
  1242. md5_state_t state;
  1243. md5_byte_t digest[16];
  1244. char hex_output[16*2 + 1];
  1245. int di;
  1246. md5_init(&state);
  1247. md5_append(&state, (const md5_byte_t *)str, strlen(str));
  1248. md5_finish(&state, digest);
  1249. for (di = 0; di < 16; ++di)
  1250. sprintf(hex_output + di * 2, "%02x", digest[di]);
  1251. NSString *retValue = [[NSString alloc] initWithUTF8String:hex_output];
  1252. return([retValue autorelease]);
  1253. }
  1254. NSString* md5sig(NSDictionary* parameters) {
  1255. NSMutableString *sigstr=[NSMutableString stringWithString:@SHARED_SECRET];
  1256. NSArray *sortedkeys=[[parameters allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  1257. NSMutableString *urlParam=[NSMutableString stringWithString:@""];
  1258. unsigned i, c=[sortedkeys count];
  1259. for (i=0; i<c; i++) {
  1260. NSString *k=[sortedkeys objectAtIndex:i];
  1261. NSString *v=[parameters objectForKey:k];
  1262. [sigstr appendString:k];
  1263. [sigstr appendString:v];
  1264. }
  1265. NSString* md5 = getmd5([sigstr UTF8String]);
  1266. [urlParam appendString:md5];
  1267. return urlParam;
  1268. }
  1269. int callback(void *connection, CFStringRef string, CFDictionaryRef dictionary, void *data) {
  1270. NSLog(@"callback (but it never calls me back :( ))\n");
  1271. CFShow(string);
  1272. CFShow(dictionary);
  1273. return 0;
  1274. }
  1275. void sourcecallback ( CFMachPortRef port, void *msg, CFIndex size, void *info)
  1276. {
  1277. NSLog(@"Source called back\n");
  1278. //getCellInfo();
  1279. }
  1280. void mycallback (void)
  1281. {
  1282. NSLog(@"My called back\n");
  1283. }