@@ -135,6 +135,7 @@ const uint32_t restab[CAMERA_RMAX][2] = {
135
135
{320 , 240 },
136
136
{320 , 320 },
137
137
{640 , 480 },
138
+ {0 , 0 }, // Empty entry because there's a jump in the resolution enum initializers
138
139
{800 , 600 },
139
140
{1600 , 1200 },
140
141
};
@@ -502,36 +503,120 @@ int Camera::setFrameRate(int32_t framerate)
502
503
return -1 ;
503
504
}
504
505
505
- int Camera::setResolution (int32_t resolution)
506
+ int Camera::setResolutionWithZoom (int32_t resolution, int32_t zoom_resolution, int32_t zoom_x, int32_t zoom_y )
506
507
{
507
508
if (this ->sensor == NULL || resolution >= CAMERA_RMAX
508
509
|| pixformat >= CAMERA_PMAX || pixformat == -1 ) {
509
510
return -1 ;
510
511
}
511
512
513
+ // resolution = the full resolution to set the camera to
514
+ // zoom_resolution = the resolution to crop to when zooming (set equal to resolution for no zoom)
515
+ // final_resolution = the resolution to crop to (depends on zoom or not)
516
+ int32_t final_resolution;
517
+ // Check if zooming is asked for
518
+ if (resolution != zoom_resolution)
519
+ {
520
+ // Can't zoom into a larger window than the original
521
+ if (zoom_resolution > resolution)
522
+ {
523
+ return -1 ;
524
+ }
525
+ final_resolution = zoom_resolution;
526
+ }
527
+ else
528
+ {
529
+ final_resolution = resolution;
530
+ }
531
+
512
532
/*
513
533
* @param X0 DCMI window X offset
514
534
* @param Y0 DCMI window Y offset
515
535
* @param XSize DCMI Pixel per line
516
536
* @param YSize DCMI Line number
517
537
*/
518
538
HAL_DCMI_EnableCROP (&hdcmi);
519
- uint32_t bpl = restab[resolution ][0 ];
539
+ uint32_t bpl = restab[final_resolution ][0 ];
520
540
if (pixformat == CAMERA_RGB565 ||
521
541
(pixformat == CAMERA_GRAYSCALE && !this ->sensor ->getMono ())) {
522
542
// If the pixel format is Grayscale and sensor is Not monochrome,
523
543
// the actual pixel format will be YUV (i.e 2 bytes per pixel).
524
544
bpl *= 2 ;
525
545
}
526
- HAL_DCMI_ConfigCROP (&hdcmi, 0 , 0 , bpl - 1 , restab[resolution ][1 ] - 1 );
546
+ HAL_DCMI_ConfigCROP (&hdcmi, 0 , 0 , bpl - 1 , restab[final_resolution ][1 ] - 1 );
527
547
528
- if (this ->sensor ->setResolution (resolution) == 0 ) {
529
- this ->resolution = resolution ;
548
+ if (this ->sensor ->setResolution (resolution, zoom_resolution, zoom_x, zoom_y ) == 0 ) {
549
+ this ->resolution = final_resolution ;
530
550
return 0 ;
531
551
}
532
552
return -1 ;
533
553
}
534
554
555
+ int Camera::setResolution (int32_t resolution)
556
+ {
557
+ // Check for resolutions that would cause out-of-bounds indexing of restab
558
+ // This check is here because original_resolution will be trusted in all other code
559
+ if ((resolution < 0 ) || (resolution >= CAMERA_RMAX))
560
+ {
561
+ return -1 ;
562
+ }
563
+ original_resolution = resolution;
564
+ return setResolutionWithZoom (resolution, resolution, 0 , 0 );
565
+ }
566
+
567
+ int Camera::zoomTo (int32_t zoom_resolution, uint32_t zoom_x, uint32_t zoom_y)
568
+ {
569
+ // Check for zoom resolutions that would cause out-of-bounds indexing of restab
570
+ if ((zoom_resolution < 0 ) || (zoom_resolution >= CAMERA_RMAX))
571
+ {
572
+ return -1 ;
573
+ }
574
+ // Check if the zoom window goes outside the frame on the x axis
575
+ // Notice that this form prevents uint32_t wraparound, so don't change it
576
+ if (zoom_x >= (restab[this ->original_resolution ][0 ]) - (restab[zoom_resolution][0 ]))
577
+ {
578
+ return -1 ;
579
+ }
580
+ // Check if the zoom window goes outside the frame on the y axis
581
+ // Notice that this form prevents uint32_t wraparound, so don't change it
582
+ if (zoom_y >= (restab[this ->original_resolution ][1 ]) - (restab[zoom_resolution][1 ]))
583
+ {
584
+ return -1 ;
585
+ }
586
+ return setResolutionWithZoom (this ->original_resolution , zoom_resolution, zoom_x, zoom_y);
587
+ }
588
+
589
+ int Camera::zoomToCenter (int32_t zoom_resolution)
590
+ {
591
+ // Check for zoom resolutions that would cause out-of-bounds indexing of restab
592
+ if ((zoom_resolution < 0 ) || (zoom_resolution >= CAMERA_RMAX))
593
+ {
594
+ return -1 ;
595
+ }
596
+ uint32_t zoom_x = (restab[this ->original_resolution ][0 ] - restab[zoom_resolution][0 ]) / 2 ;
597
+ uint32_t zoom_y = (restab[this ->original_resolution ][1 ] - restab[zoom_resolution][1 ]) / 2 ;
598
+ return setResolutionWithZoom (this ->original_resolution , zoom_resolution, zoom_x, zoom_y);
599
+ }
600
+
601
+ int Camera::setVerticalFlip (bool flip_mode)
602
+ {
603
+ return (this ->sensor ->setVerticalFlip (flip_mode));
604
+ }
605
+
606
+ int Camera::setHorizontalMirror (bool mirror_mode)
607
+ {
608
+ return (this ->sensor ->setHorizontalMirror (mirror_mode));
609
+ }
610
+
611
+ uint32_t Camera::getResolutionWidth ()
612
+ {
613
+ return (restab[this ->original_resolution ][0 ]);
614
+ }
615
+ uint32_t Camera::getResolutionHeight ()
616
+ {
617
+ return (restab[this ->original_resolution ][1 ]);
618
+ }
619
+
535
620
int Camera::setPixelFormat (int32_t pixformat)
536
621
{
537
622
if (this ->sensor == NULL || pixformat >= CAMERA_PMAX) {
0 commit comments